• C++98 类的三大基本原则 与 c++11 的五大基本原则


    #include <iostream>
    #include <string>
    #include <vector>
    #include <cstring>
    #include <cassert>
    
    class RuleOfFive;  //前置声明class
    class Parent;
    class Child {
    	public:
    		explicit Child(Parent *p) : m_parent(p) {}
    	private:
    		Parent *m_parent;
    };
    class Parent {
    	public:
    		//                           等同于: m_children.push_back(child)
    		bool addChild(Child* child) {m_children.emplace_back(child); }
    	private:
    		std::vector<Child*> m_children;
    
    };
    //类的基本三大原则:
    //类的构造
    //类的析构
    //类的复制
    //若c++98中,不想复制的话,把构造函数设为私有变量, 并不实现构造函数
    //不然编译器会自动生成一个对应的构造函数
    //c++11 中: RuleOfThree(const RuleOfThree& other) = delete;
    
    class RuleOfThree {
    	public:
    		RuleOfThree(const char* arg) : cstring(new char[std::strlen(arg) + 1]){ //allocate
    			std::strcpy(cstring, arg); //populate	
    		}
    		~RuleOfThree() {
    			delete[] cstring;	
    		}
    		//c++ 11中,声明该构造不能用, 以防编译器自动生成一个构造函数
    		RuleOfThree(const RuleOfThree& other)  = delete;
    		//	{//copy constructor
    		//		cstring = new char[std::strlen(other.cstring) + 1];
    		//		std::strcpy(cstring, other.cstring);
    		//	}
    		RuleOfThree& operator = (const RuleOfThree& other) {
    			char *tmp_cstring = new char[std::strlen(other.cstring) + 1];	
    			std::strcpy(tmp_cstring, other.cstring);
    			delete[] cstring;
    		}
    	private:
    		char* cstring;
    
    };
    //c++11
    //类的5大基本原则:
    //采用左值或者右值进行构造,编译器会对不同的构造函数进行构造.
    class RuleOfFive {
    	public:
    		//只能针对与右值进行构造
    		RuleOfFive(RuleOfFive&& rhs) {
    			std::cout << "右值构造.." << std::endl;
    			std::cout << rhs.m_value;
    			m_value = rhs.m_value;
    			rhs.m_value = nullptr;
    		};
    		RuleOfFive() : m_value(new int(10) ) {}
    		//采用右值或者左值进行构造
    		RuleOfFive(const RuleOfFive &rhs) : m_value(new int(* (rhs.m_value))) {
    			std::cout << "左值或者右值构造.." << std::endl;
    		}
    		RuleOfFive& operator = (const RuleOfFive &rhs) {
    			delete m_value; //删掉以前的
    			*m_value = *(rhs.m_value);
    			return *this;
    		}
    		//对= 操作符进行右值重载
    		RuleOfFive& operator=(RuleOfFive&& rhs) {
    			m_value = rhs.m_value;	
    			rhs.m_value = nullptr;
    			return *this;
    		}
    		void print() const {
    			assert(m_value && "class print: "); //不推荐使用if来判断
    			std::cout << "value: " << *m_value << std::endl;
    		}
    		~RuleOfFive() { delete m_value; }
    	private:
    		int *m_value;
    };
    //左值和右值的定义:
    //1. 能够取到地址的值称为左值,否则为右值
    void leftOrRight() {
    	int a = 0;
    	int b;
    	int c = 2 + 3;
    	int d = a + c;
    	auto address = &a;
    	//auto address2 = &(2 + 3);
    	int& e = a; //左值引用
    	//int& e2 = 3; //错误
    	int&& e3 = 3; //右值引用.
    }
    //c++11增加了左值和右值的概念, 所以类的从3大基本原则变为了5大基本原则
    void leftAndRight() {
    	std::vector<int> a; //left
    	for(int i = 0; i < 10; ++i) a.push_back(i);
    	auto b = a; //b as left value
    	auto &c = b; //c as left value
    	//std::vector<int>& c = b; //c as left value
    	//move函数啥也不干,就是让编译器把b转换为右值.
    	auto d = std::move(b);//std::move(b) 就为右值了
    	RuleOfFive f;
    	RuleOfFive g(f); //左值构造
    	RuleOfFive h (std::move(f)); //右值构造, f已经毫无意义
    //	f.print(); //m_value 已经为nullptr
    }
    
    int main(void) {
    
    	leftAndRight();
    	return 0;
    }
    
  • 相关阅读:
    更改已经签名的app中的内容
    POJ 1611 The Suspects
    hibernate session缓存
    男儿当自强
    图遍历的演示
    nginx源代码分析--事件模块 &amp; 琐碎
    多线程在python中的使用 thread
    机房收费 &amp; 廊院食堂
    the steps that may be taken to solve a feature selection problem:特征选择的步骤
    早绑定和迟绑定技术的通俗分析
  • 原文地址:https://www.cnblogs.com/lyxf/p/12358177.html
Copyright © 2020-2023  润新知