C++ 拷贝构造
2022/6/17 1:22:38
本文主要是介绍C++ 拷贝构造,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
12 拷贝构造
- Create a new object from an existing one
- For example, when calling a function
// Currency as pass-by-value argument void func(Currency p) { cout << "X = " << p.dollars(); } Currency bucks(100, 0); func(bucks); // bucks is copied into p
- 示例二:
#include <iostream> #include <string> using namespace std; static int objectCount = 0; class HowMany { public: HowMany() { objectCount++; print("HowMany()"); } void print(const string& msg = "") { if (msg.size() != 0) { cout << msg << ": "; } cout << "objectCount = " << objectCount << endl; } ~HowMany() { objectCount--; print("~HowMany()"); } }; HowMany f(HowMany x) { cout << "begin of f " << endl; x.print("x argument inside f() "); cout << "end of f" << endl; return x; } int main() { HowMany h; h.print("after construction of h"); HowMany h2 = f(h); h.print("after call to f()"); }
- 示例三:
#include <iostream> #include <string> using namespace std; static int objectCount = 0; class HowMany { public: HowMany() { objectCount++; print("HowMany()"); } HowMany(int i) { objectCount++; print("HowMany(int)"); } // 拷贝构造 HowMany(const HowMany& o) { objectCount++; print("HowMany(HM)"); } void print(const string& msg = "") { if (msg.size() != 0) { cout << msg << ": "; } cout << "objectCount = " << objectCount << endl; } ~HowMany() { objectCount--; print("~HowMany()"); } }; HowMany f(HowMany x) { cout << "begin of f " << endl; x.print("x argument inside f() "); cout << "end of f" << endl; return x; } int main() { HowMany h; h.print("after construction of h"); // 这种方式,是可以初始化 h2 的 HowMany h2 = 10; // HowMany h2 = h; HowMany h3 = f(h); h.print("after call to f()"); }
12.1 The copy cosntructor
- Copying is implemented by the copy cosntructor
- Has the unique signature:
T::T(cosnt T&);
- Call-by-reference is used for the explicit argument
- C++ builds a copy constructor for you if you don't provide one!
- Copies each member variable
- Good for numbers, objects, arrays
- Copies each pointer
- Data may become shared!
- Copies each member variable
12.2 class contains pointers
- 示例一:
#include <iostream> #include <stdio.h> #include <cstring> using namespace std; class Person { public: Person(const char *s); ~Person(); void print(); // private: char *name; }; Person::Person(const char *s) { name = new char[::strlen(s) + 1]; ::strcpy(name, s); } Person::~Person() { delete []name; } int main() { Person p1("John"); Person p2(p1); printf("p1.name = %p\n", p1.name); printf("p2.name = %p\n", p2.name); return 0; } // p1.name 和 p2.name 指向同一个地址,析构的时候,会析构两次; // 程序运行会报错。
- 示例二:
Person copy constructor
#include <iostream> #include <stdio.h> #include <cstring> using namespace std; class Person { public: Person(const char *s); // 自定义拷贝构造 Person(const Person& w); ~Person(); void print(); // private: char *name; }; Person::Person(const char *s) { name = new char[::strlen(s) + 1]; ::strcpy(name, s); } Person::Person(const Person& w) { name = new char[::strlen(w.name) + 1]; ::strcpy(name, w.name); } Person::~Person() { delete []name; } int main() { Person p1("John"); Person p2(p1); printf("p1.name = %p\n", p1.name); printf("p2.name = %p\n", p2.name); return 0; }
- 总结:
12.3 When are copy constructor called?
- During call by value
void roster(Person); // 函数声明 Person child("Tom"); // 创建对象 roster(child); // 调用函数,参数为对象本身
- During initialization
Person baby_a("Fred"); // 以下需要使用 copy constructor Person baby_b = baby_a; // not an assignment Person baby_c(baby_a); // not an assignment
- During function return
Person f() { Person player("Musk"); return player; } int main() { Person p = f(); return 0; }
12.3.1 编译器对拷贝的优化
- Compilers can "optimize out" copies when safe!
// 示例一: Person copy_func(char *who) { Person local(who); local.print(); return local; // copy constructor called! } // 示例二: Person nocopy_func(char *who) { return Person(who); // no copy needed! }
12.4 Construction vs. assignment
- Every object is constructed once.
- Every object should be destroyed once
- Failure to invoke delete()
- Invoking delete() more than once
- Once an object is constructed, it can be the target of many assignment operations.
12.5 Copy constructor guidelines
- In general, be explicit
- Create your own copy constructor -- don't rely on the default
- If you don't need one, declare a private copy constructor
- prevents creation of a default copy constructor
- generates a compiler error if try to pass-by-value
- don't need a definition
参考资料:
- 翁凯 C++
这篇关于C++ 拷贝构造的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享