本文主要复习了c++构造函数的用法,然后对匿名对象的声明周期和C++的静态变量和静态成员函数的用法做了一些总结。
文章有如下三点:
1、主要讨论匿名对象的声明周期
2、引出的一个在构造函数中再一次调用构造函数的这种现象。
3、静态变量和静态成员函数使用中需要注意的地方。
class ABCD
{
public:
ABCD(int a, int b, int c)
{
this->a = a;
this->b = b;
this->c = c;
printf("ABCD() construct, a:%d,b:%d,c:%d \n", this->a, this->b, this->c);
}
~ABCD()
{
printf("~ABCD() construct,a:%d,b:%d,c:%d \n", this->a, this->b, this->c);
}
int getA()
{
return this->a;
}
protected:
private:
int a;
int b;
int c;
};
class MyE {
public:
MyE():abcd1(1,2,3),abcd2(4,5,6),m(100)
{
cout<<"MyD()"<<endl;
}
~MyE()
{
cout<<"~MyD()"<<endl;
}
MyE(const MyE & obj):abcd1(7,8,9),abcd2(10,11,12),m(100)
{
printf("MyD(const MyD & obj)\n");
}
protected:
private:
ABCD abcd1; //在没有默认构造函数的情况下,c++编译器是不知道如何构造它的,因此需要用初始化列表初始化。见MyE 的默认构造函数和 赋值构造函数
ABCD abcd2;
const int m;
};
int doThing(MyE mye1)
{
printf("doThing() mye1.abc1.a:%d \n", mye1.abcd1.getA());
return 0;
}
int run2()
{
MyE myE;
doThing(myE);
return 0;
}
int run3()
{
printf("run3 start..\n");
ABCD abcd = ABCD(100, 200, 300); //再这个run3() 结束之后再进行析构
//想调用构造函数对abc对象进行再复制,可以吗?
//在构造函数里面调用另外一个构造函数,会有什么结果? 具体的情况,见下面的例子
//ABCD(400, 500, 600); // /临时对象的生命周期,C++会构造一个临时对象,但是由于没有用到,变直接给析构掉,打印构造和析构两个函数
printf("run3 end\n");
return 0;
}
int main()
{
//run2();
cout<<"run 2"<<endl;
run3();
cout<<"run 3"<<endl;
return 0;
}
举例说明在构造函数中再一次调用构造函数是什么情况,主要也是讨论匿名对象的声明周期。
class MyTest {
public:
MyTest(int a, int b, int c)
{
this->a = a;
this->b = b;
this->c = c;
}
MyTest(int a, int b)
{
this->a = a;
this->b = b;
MyTest(a, b, 100); //在构造函数中再 调用一次构造函数。
}
~MyTest()
{
printf("MyTest~:%d, %d, %d\n", a, b, c);
}
protected:
private:
int a;
int b;
int c;
public:
int getC() const { return c; }
void setC(int val)
{
c = val;
}
};
int main()
{
MyTest t1(1, 2); //在构造函数的中调用的构造函产生的临时变量在此就会析构掉。c 的值仍然是未定义的。
printf("c:%d\n", t1.getC());
//请问c的值是? 结果不可预测。
return 0;
}
打印的结果如下:
MyTest~:1, 2, 100
c:4196336
MyTest~:1, 2, 4196336
第一行 :是在构造函数中再次调用构造函数的临时变量调用的析构函数。 这个也对应着上面一个例子中的匿名对象的生命周期。
第三行 :是打印的t1 的值,t1 中的c 值是未定义的,因此打印的是一个不确定的数。
三、静态变量和静态成员函数
1、静态变量属于整个类,不属于某一个对象,静态类成员有一个特点,就是无论创建多少对象,程序只创建一个静态类变量副本。
2、静态变量的存储位置为全局数据区。
3、不能再类的声明中初始化静态成员变量,因为声明描述了如何分配内存,但是不分配内存。
4、不能通过对象调用静态成员函数,实际上静态成员函数不能使用this 指针,因为它属于这个类,不属于具体的对象。
5、静态成员函数不与特定的对象相关联,因此只能使用静态数据成员。
class BB
{
public:
int getC()
{
return c;
}
void setC(int nyc)
{
c = nyc;
}
//静态成员函数是属于整个类,
//在类的静态数据成员函数中,是不能调用具体的对象的变量的属性。。。。(抛砖)
//不能调用普通成员变量
static void getMem()
{
//cout<<a<<endl;
cout<<c<<endl;
}
protected:
private:
int a;
int b;
static int c;
};
int BB::c = 0; //静态变量的初始化,得在类的外面。