一旦写了一个类,给它3个函数:
1default construtor
2virtual destructor
3copy constructor
Constructions vs. assignment
Every object is constructed once
Every object should be destroyed once
--Failure to invoke delete()
--invoke delete() more than once
Once an object is constructed, it can be the target of many assignment operations
Copy ctor guidelines
In general, be explicit
--Create your own copy ctor--don't rely on the default
If you don't need one declare a private copy ctor
--prevents creation of a default copy constructor
--generates a compiler error if try to pass-by-value
--don't need a definition
复制构造函数,不是字节对字节的拷贝,而是成员对成员的拷贝
构造函数,参数是引用一个类
正确
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 static int objectCount = 0; 6 7 class HowMany 8 { 9 public: 10 HowMany() { objectCount++; print("HowMany()"); }//构造函数,没有参数 11 HowMany(int i) { objectCount++; print("HowMany(int)"); }//构造函数,参数是一个int 12 HowMany(const HowMany& o) { objectCount++; print("HowMany(HM)"); }//构造函数,参数是引用一个类 13 void print(const string& msg = "") 14 { 15 if (msg.size() != 0) 16 { 17 std::cout << msg << ": "; 18 } 19 std::cout << "objectCount=" 20 << objectCount << std::endl; 21 } 22 ~HowMany() 23 { 24 objectCount--; 25 print("~HowMany()"); 26 } 27 }; 28 29 HowMany f(HowMany x) 30 { 31 std::cout << "begin of f" << std::endl; 32 x.print("x argument inside f()"); 33 std::cout << "end of f" << std::endl; 34 return x; 35 } 36 37 void main() 38 { 39 HowMany h; 40 h.print("after construction of h"); 41 42 HowMany h2 = f(h); 43 //HowMany h2 = h; 44 //HowMany h2(10);//构造函数,参数是一个int 45 //HowMany h2(h);//构造函数,参数是一个类 46 47 h.print("after call to f()"); 48 49 system("pause"); 50 }
构造函数,参数是新建一个类,形成死循环
错误
1>main.cpp(13): error C2652: “HowMany”: 非法的复制构造函数: 第一个参数不应是“HowMany”
1> main.cpp(8): note: 参见“HowMany”的声明
1>main.cpp(13): error C2333: “HowMany::HowMany”: 函数声明中有错误;跳过函数体
1>main.cpp(44): error C2440: “return”: 无法从“HowMany”转换为“HowMany”
1> main.cpp(44): note: 由于复制构造函数不明确或没有可用的复制构造函数,因此无法复制构造 class“HowMany”
1>main.cpp(52): error C2664: “HowMany f(HowMany)”: 无法将参数 1 从“HowMany”转换为“HowMany”
1> main.cpp(52): note: 由于复制构造函数不明确或没有可用的复制构造函数,因此无法复制构造 class“HowMany”
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 static int objectCount = 0; 6 7 class HowMany 8 { 9 public: 10 HowMany() { objectCount++; print("HowMany()"); }//构造函数,没有参数 11 HowMany(int i) { objectCount++; print("HowMany(int)"); }//构造函数,参数是一个int 12 13 HowMany(HowMany o) { objectCount++; print("HowMany(HM)"); }//构造函数,错误,参数是新建一个类,形成死循环 14 15 //1>main.cpp(13) : error C2652 : “HowMany” : 非法的复制构造函数 : 第一个参数不应是“HowMany” 16 // 1> main.cpp(8) : note : 参见“HowMany”的声明 17 // 1>main.cpp(13) : error C2333 : “HowMany::HowMany” : 函数声明中有错误;跳过函数体 18 // 1>main.cpp(44) : error C2440 : “return” : 无法从“HowMany”转换为“HowMany” 19 // 1> main.cpp(44) : note : 由于复制构造函数不明确或没有可用的复制构造函数,因此无法复制构造 class“HowMany” 20 // 1>main.cpp(52) : error C2664 : “HowMany f(HowMany)” : 无法将参数 1 从“HowMany”转换为“HowMany” 21 // 1> main.cpp(52) : note : 由于复制构造函数不明确或没有可用的复制构造函数,因此无法复制构造 class“HowMany” 22 23 void print(const string& msg = "") 24 { 25 if (msg.size() != 0) 26 { 27 std::cout << msg << ": "; 28 } 29 std::cout << "objectCount=" 30 << objectCount << std::endl; 31 } 32 ~HowMany() 33 { 34 objectCount--; 35 print("~HowMany()"); 36 } 37 }; 38 39 HowMany f(HowMany x) 40 { 41 std::cout << "begin of f" << std::endl; 42 x.print("x argument inside f()"); 43 std::cout << "end of f" << std::endl; 44 return x; 45 } 46 47 void main() 48 { 49 HowMany h; 50 h.print("after construction of h"); 51 52 HowMany h2 = f(h); 53 //HowMany h2 = h; 54 //HowMany h2(10);//构造函数,参数是一个int 55 //HowMany h2(h);//构造函数,参数是一个类 56 57 h.print("after call to f()"); 58 59 system("pause"); 60 }
如果一个类有指针,需要另外写复制构造函数,否则出错
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <iostream> 3 using namespace std; 4 5 class Person 6 { 7 public: 8 Person(const char *s); 9 ~Person(); 10 void print(); 11 char *name; 12 }; 13 14 Person::Person(const char *s) 15 { 16 name = new char[::strlen(s) + 1]; 17 ::strcpy(name, s); 18 } 19 20 Person::~Person() 21 { 22 delete[] name;//array delete 23 } 24 25 void Person::print() 26 { 27 std::cout << name << std::endl; 28 } 29 30 void main() 31 { 32 Person p1("John"); 33 Person p2(p1); 34 35 p1.print(); 36 p2.print(); 37 38 printf("p1.name=%p\n", p1.name);//一样 39 printf("p2.name=%p\n", p2.name);//一样 40 41 system("pause"); 42 }