1.构造函数的3种类型 无参Test(); 有参 Test(int a,int b);复制构造函数 Test(const Test2& obj)
#include<iostream>
class Test2
{
public:
Test2() //无参构造函数
{
m_a = 0;
m_b = 0;
std::cout <<"这是无参构造函数" <<std::endl;
}
// 有参构造函数
Test2(int a)
{
m_a = a;
m_b = 0;
std::cout <<"这是含一个参数的构造器" <<std::endl;
}
Test2(int a,int b)
{
m_a = a;
m_b = b;
std::cout <<"这是有参构造函数"<<std::endl;
}
// 复制构造函数(copy构造函数)
//copy构造函数主要完成用一个对象去初始化另一个对象
Test2(const Test2& obj)
{
std::cout <<"这是赋值构造函数"<<std::endl;;
}
void printp()
{
std::cout <<"被调用的函数"<<std::endl;
}
private:
int m_a;
int m_b;
};
void main02()
{
Test2 t1;//这是调用无参构造函数
system("pause");
return;
}
void main03()
{
//调用参数构造函数,括号里必须写上参数 括号法
Test2 t2(1,2);
t2.printp();
// 等号法 这个调用的是一个参数的构造器函数
Test2 t3 = (3,4);//C++对=功能的加强 相当于t3 = 4 t3等于括号中的最后一个值
t3.printp();
//前面这两个都是C++编译器帮我调用构造函数
// 直接调用法 手动
Test2 t4 = Test2(1,2);
system("pause");
return ;
}
2.赋值操作和初始化是不同的,虽然都是用等号表示
Eg: Test t1(1,2);Test t0(3,4);
Test t2 = t1 //表示用t1来初始化t2
t0 = t1 //用t1给t0赋值 虽然都是等号,但是表示意义完全不同
有参构造函数的三种调用方法:
1)Test t1(10); 2)Test t1 = 10; 3)Test t1 = Test(5)// Test(5) 类似于一个匿名对象
3.调用复制构造函数的四种情况:复制构造函数主要用来完成用一个对象来初始化另一个对象
a) Test t1(1,2);Test t2 =t1;
b) Test t3(t1);
c)void f(Test p); f(t1) 用对象作为实参初始化函数的形参
d) Test g() 当返回值是一个对象时,则会调用复制构造函数
{ Test A;
return A;
}
#include<iostream>
class Test3
{
public:
Test3() //无参构造函数
{
m_a = 0;
m_b = 0;
std::cout <<"这是无参构造函数" <<std::endl;
}
// 有参构造函数
Test3(int a)
{
m_a = a;
m_b = 0;
std::cout <<"这是含一个参数的构造器" <<std::endl;
}
Test3(int a,int b)
{
m_a = a;
m_b = b;
std::cout <<"这是有参构造函数"<<std::endl;
}
// 复制构造函数(copy构造函数)
//copy构造函数主要完成用一个对象去初始化另一个对象
Test3(const Test3& obj) // 这么写是标准格式
{
std::cout <<"这是复制构造函数"<<std::endl;
m_a = obj.m_a + 100;
m_b = obj.m_b + 100;
}
void printp()
{
std::cout <<"被调用的函数"<<std::endl;
std::cout <<"m_a = "<<m_a<<"m_b = "<<m_b<<std::endl;
}
int Geta()
{
return m_a;
}
private:
int m_a;
int m_b;
};
void f(Test3 p)
{
std::cout <<"A的值为"<<p.Geta()<<std::endl;
}
// 返回值是一个复杂类型的元素,称其为匿名对象,这是会调用复制构造函数
Test3 g()
{
Test3 A(3,4);
return A;
}
void Testplay()
{
g();
}
void Testplay2()
{
Test3 m = g();//匿名对象初始化对象m,直接把匿名对象转正,从匿名变成了有对象的m了
}
void Testplay3()
{
Test3 m2(1,2);
m2 = g(); // 匿名对象赋值给m2,匿名对象被析构
}
void main()
{
Test3 t1(1,2);
Test3 t0(1,2);
// 方法1 调用构造函数
Test3 t2 = t1; // 用t1来初始化t2,所以他调用的是复制构造函数
t0 = t1; //给t0赋值
t2.printp();
// 方法2 调用构造函数
Test3 t3(t1); // 将一个对象作为参数
t3.printp();
//方法3 当对象作为实参初始化函数的形参时会调用复制构造函数
f(t0);
//方法4
Testplay();
system("pause");
return ;
}
4.如3中的g()称之为匿名对象:
如果用匿名对象初始化一个同类型的对象,则匿名对象被“扶正”,不会被析构器析构
Eg: Test m = g()
如果匿名对象赋值给一个同类型的对象,则匿名对象会被析构
Eg: Test3 m2(1,2); m2 = g();
5.如果在类定义中写了复制构造器,则编译器不会再为类生成一个无参构造器,如果定义了有参构造器时,编译器也不会提供一个无参的构造函数。总之,在定义类时只要写了构造函数就一定要用。
如果在调用时调用的是一个有参或copy类型的构造函数 Eg:Test obj1(“abcd0”),但是在开始时并没有定义这种类型的构造器,则系统就会报错。