class Per {
char p_name;
int p_age;
public:
//构造
Per() {};
Per(int age) {
p_age = age;
}
Per(char name, int age) {
p_name = name;
p_age = age;
}
//拷贝构造函数
Per(const Per& p) {
p_name = p.p_name;
p_age = p.p_age;
cout << "拷贝构造函数" << endl;
}
//析构
~Per() {
cout << "析构" << endl;
}
};
对构造函数的调用
//构造调用
void invoke() {
//括号法,无参会被当作函数声明
Per p1;
Per p2('a', 21);
Per p3(p2);
Per p();//无参会被当作函数声明
//显示法,不要利用拷贝函数初始化匿名对象
Per p4 = Per('b', 21);
Per p5 = Per();
Per p6 = Per(p4);
//Per p7(p6);//不要利用拷贝函数初始化匿名对象相当于Per p(p0)==Person p0;
//隐式转换
Per p11 = 21;//相当于Per p11(21);
}
特别注意的是在用指针成员属性的时候操作
#includeusing namespace std; class Per { public: int* name; public: Per(int n) { cout <<"打印n的地址:"<< &n << endl; name = &n; cout <<"打印name的值:"<< *name << endl; } ~Per(){}; }; void test() { Per p1 =Per (3); cout << "调用后的name所指向的地址:" << p1.name << endl; cout << "地址里的值: " << *p1.name << endl; Per p2 = (p1);//编译器调用自己创建的拷贝函数此时对堆区的数据为浅拷贝 } int main() { test(); }
可以看到最后一行的输出的值以经不是3了,因为00EFFB8C地址的面的数据以经被编译器清除了。清除的原因是因为之前说的刚开始传进去的参数n在栈区,在函数执行完会被释放。
void test(Per p)
{
//形参在拷贝传递过来的对象
}
Per test2() {
Per p;//注意
return p;//这两个p不是一个东西这个p是拷贝的上一个p
}
//拷贝构造函数的应用
void copyFunc()
{
//
Per p('c', 21);
Per p1(p);
//值传递的方式给函数参数传值
test(p1);
//值的方式返回局部变量
Per p2=test2();
}
构造函数的规则
//构造函数的调用规则 //如果自己创建了有参构造,编译器就不会提供无参的了,但会提供拷贝构造 //如果自己创建了拷贝构造,编译器什么构造函数也不会提供



