C++之旅:拷贝构造与友元 拷贝构造与友元

拷贝构造是在构造一个对象的时候将已有对象的属性拷贝给新的对象;友元可以让一个类的所有属性(主要是private)对特定的类开放

拷贝构造

如果没有复写拷贝构造函数,系统会帮我们默认生成改函数

#include <iostream>
using namespace std;

class Demo {
	private:
		int a;
	public:
		void set(int a) {this->a = a;}
		int get() {return a;}
};


int main(int argc, char **argv) {
	Demo demo;
	demo.set(100);
	Demo demo1 = demo;        //调用拷贝构造函数
	cout << demo1.get() << endl;
}

在上面的代码中,即使a是私有成员,也会将其值赋给新对象,因为拷贝构造是全员拷贝的。

Demo demo1 = demo;

上面的代码在编译时会被翻译成下面的代码(其实是=号操作符被重载了),我们也可以使用下面的代码显示的调用拷贝构造函数

Demo demo1(demo);

涉及到指针的拷贝

如果类成员中有指针,则需要自己实现拷贝构造函数,即进行深拷贝。

class Demo {
	private:
		char *str;
	public:
		Demo(){str = new char[10];}
		~Demo(){delete []str;}
		Demo(const Demo &demo) {   //自定义拷贝构造函数
			str = new char[10];
			strcpy(str, demo.str);
		}
};

上面的代码中新对象和旧对象中str指针将会指向不同的内存区域。如果我们不实现拷贝构造,那么编译器会简单的将旧对象中str的值赋值给新对象,这样两个对象中str将会指向同一块内存区域,比较危险

拷贝构造与赋值操作

int main(int argc, char **argv) {
	Demo demo;
	Demo demo2;
	demo2 = demo;   // 不会调用拷贝构造
	Demo demo3 = demo;   // 调用拷贝构造
}

在main函数的第三行代码中只是发生了赋值操作,即将demo对象中所有的属性赋值给demo2,并不会调用拷贝构造函数(这里可能会引起内存泄露);在第四行代码中将会发生拷贝构造

友元

友元类

友元是将自己本来不想开放的属性和方法对特定的类进行开放。
**友元关系是单向的,且友元关系不具备传递性"

#include <iostream>
#include <cstring>
using namespace std;

class Demo {
	private:
		char *str;
		void test(){cout << "this is demo" << endl;}
	friend class Demo1;
	
};

class Demo1 {
	public:
		Demo1(){Demo demo; demo.test();}
};

int main(int argc, char **argv) {
	Demo1 demo1;
}

上面的例子中Demo将Demo1设为自己的友元,所以在Demo1可以访问Demo中的私有属性。

友元方法

#include <iostream>
#include <cstring>
using namespace std;

class Demo {
	private:
		char *str;
		void test(){cout << "this is demo" << endl;}
	friend void test();   
};

void test() {
	Demo demo;
	demo.test();
}

int main(int argc, char **argv) {
	test();
}

将某个方法设置为自己的友元方法,但是在面向对象编程中一般很少用到友元方法