1.我是新手,我会犯错
32 class Child {
33 int i;
34 //Member m;
35 public:
36 Child() : i(0) {
37 cout << "Child()" << endl;
38 }
39
40 Child(const Child& c) : Parent(c), i(c.i) {
41 cout << "Child(const Child&)" << endl;
42 }
43
44 Child& operator=(const Child& c) {
45 i = c.i;
46 cout << "Child& operator=(const Child&)" << endl;
47 }
48 ~Child() {
49 cout << "~Child()" << endl;
50 }
51 };
52
53 int main() {
54 Child c;
55
56 Child c2 = c;
57
58 }
运行这个代码,从得到的结果中可以看出,在代码行Child c2 = c;并没有执行赋值符号中的内容,而是执行了拷贝构造函数中的内容。
为什么呢?这是我这个新手容易犯的错误。虽然Child c2 = c;使用了赋值符号,但是此处是对对象c2的定义,也就是说对象c2在没有被构造之前是不能赋值的,因此,编译器在56行代码处会调用拷贝构造函数,而不是我理解的赋值操作。
因此,为了避免这种二义性,对于对象的定义,在c++中最好使用建议的定义方式,如下面的代码
53 int main() {
54 Child c;
55
56 Child c2(c);
57
58 }
2.继承之间的构造函数如何使用
1 #include <iostream>
2 using namespace std;
3
4 class Parent {
5 int i;
6 public:
7 Parent() : i(0) {
8 cout << "Parent()" << endl;
9 }
10 Parent(const Parent& p) : i(p.i) {
11 cout << "Parent(const Parent&)" << endl;
12 }
13 ~Parent() {
14 cout << "~Parent()" << endl;
15 }
16 };
17
18 class Member {
19 int i;
20 public:
21 Member() : i(0) {
22 cout << "Member()" << endl;
23 }
24 Member(const Member& m) : i(m.i) {
25 cout << "Member(const Member&)" << endl;
26 }
27 ~Member() {
28 cout << "~Member()" << endl;
29 }
30 };
31
32 class Child : public Parent {
33 int i;
34 Member m;
35 public:
36 Child() : i(0) {
37 cout << "Child()" << endl;
38 }
39 /*
40 Child(const Child& c) : Parent(c), i(c.i) {
41 cout << "Child(const Child&)" << endl;
42 }
43 */
44 Child& operator=(const Child& c) {
45 i = c.i;
46 cout << "Child& operator=(const Child&)" << endl;
47 }
48 ~Child() {
49 cout << "~Child()" << endl;
50 }
51 };
52
53 int main() {
54 Child c;
55
56 Child c2(c);
57 }
运行结果:
引用
Parent()
Member()
Child()
Parent(const Parent&)
Member(const Member&)
~Child()
~Member()
~Parent()
~Child()
~Member()
~Parent()
可以看到,我们注释了类Child的拷贝构造函数,因此,编译器会默认为我们生成一个类Child的拷贝构造函数,这个函数的只能包括:调用父类的拷贝构造函数,然后调用成员变量的拷贝构造函数(如果存在对象成员变量)。那么,如果我们显示的定义Child的拷贝构造函数呢?
分享到:
相关推荐
- **拷贝初始化**:通过等号操作符`= new MyClass(obj)`创建对象时,调用的是拷贝构造函数。 - **赋值操作**:而当使用`= operator`为已有对象赋值时,调用的是赋值运算符`=`。这两个过程虽然类似,但不是一回事,...
在C++编程中,拷贝构造函数和赋值操作符重载是两个非常重要的概念,尤其是在处理包含动态分配资源的对象时。拷贝构造函数和赋值操作符是保证对象正确复制和赋值的关键。 拷贝构造函数是一种特殊的构造函数,其主要...
3. **复制构造函数(拷贝构造函数)**: - **定义**:其参数为同一类的另一个对象的引用。复制构造函数用于根据已存在的对象创建新的对象。 - **示例**: ```cpp class Complex { public: Complex(const ...
这些默认成员函数包括:默认构造函数、析构函数、拷贝构造函数、赋值运算符重载、等号运算符重载和地址运算符重载。 二、构造函数 构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动...
4. **默认拷贝构造函数**:默认的拷贝构造函数会简单地按成员变量逐个进行赋值,这可能不适用于复杂的数据类型,因为可能会导致浅复制问题。因此,程序员通常需要自定义拷贝构造函数以实现深复制。 总结来说,一旦...
首先c++里的各种运算符都是用函数实现的,比如=,就等号函数。 所以当用=给一个对象赋值的时候,实际调用的是=号所对应的=号函数。 分析下面的代码 ... //拷贝构造函数 Test(const Test &t){ cout << Co
- 当定义类类型的变量时,推荐使用直接初始化(直接用花括号 `{}` 初始化)而不是拷贝初始化(用等号 `=` 初始化),以避免不必要的拷贝构造函数调用。 3. **资源管理与特殊函数**: - 对于管理资源的类,如动态...
- **不要轻视拷贝构造函数与赋值函数**:强调了拷贝构造函数和赋值函数的重要性,并举例说明了不当实现可能导致的问题。 - **示例:类STRING的拷贝构造函数与赋值函数**:通过STRING类的示例具体讲解了拷贝构造函数...
`:拷贝构造函数。 list容器赋值和交换 list容器提供了多种赋值和交换函数,包括: 1. `assign(beg, end);`:将[beg, end)区间中的数据拷贝赋值给本身。 2. `assign(n, elem);`:将n个elem拷贝赋值给本身。 3. `...
### C++面经知识点详解 #### 1. main函数前后执行代码 在C++程序中,main函数执行前后会有一些特殊的代码执行。在main执行前,全局变量的构造函数会被调用;而在main函数执行结束后,全局变量的... 拷贝构造函数与赋值...
拷贝构造函数则是将一个 deque 容器拷贝给另一个 deque 容器。 deque 容器的赋值操作包括重载等号操作符、assign 函数和拷贝赋值的方式。assign 函数可以将 [beg, end) 区间中的数据拷贝赋值给本身,或者将 n 个 ...
示例:类String的拷贝构造函数与赋值函数** - 展示如何实现拷贝构造函数和赋值函数的具体方法。 **7. 偷懒的办法处理拷贝构造函数与赋值函数** - 提供一种简化拷贝构造函数和赋值函数实现的方法。 **8. 如何在...
- **拷贝构造函数与赋值函数的重要性**:拷贝构造函数和赋值函数对于实现类的深拷贝和浅拷贝至关重要。 - **拷贝构造函数与赋值函数示例**:继续以`STRING`类为例,展示拷贝构造函数和赋值函数的实现。 - **拷贝构造...
3. **拷贝构造函数**:`EnhancedSafeArray(const EnhancedSafeArray&)`。该构造函数用于创建一个新的`EnhancedSafeArray`对象,其元素与原对象相同。 4. **获取数组大小的方法**:`int size(void) const`。该方法...
如果没有RVO,那么会调用拷贝构造函数`TestConstructor(const TestConstructor&)`来生成这个临时对象,同时析构函数`~TestConstructor()`会被调用来销毁`testInFunc`。 3. **赋值操作**:回到`main()`函数,`test =...
传统的C++中,临时对象在使用后会立即被销毁,如果需要继续使用,就需要通过拷贝构造函数或赋值运算符创建新的实例,这可能导致性能上的开销。引入右值引用后,我们可以通过移动构造函数和移动赋值运算符来“移动”...