持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情。
1.3.6 说说构造函数有几种,分别什么作用
参考答案
C++中的构造函数可以分为4类:默认构造函数、初始化构造函数、拷贝构造函数、移动构造函数。
-
默认构造函数和初始化构造函数。 在定义类的对象的时候,完成对象的初始化工作。
class Student { public: //默认构造函数 Student() { num=1001; age=18; } //初始化构造函数 Student(int n,int a):num(n),age(a){} private: int num; int age; }; int main() { //用默认构造函数初始化对象S1 Student s1; //用初始化构造函数初始化对象S2 Student s2(1002,18); return 0; }有了有参的构造了,编译器就不提供默认的构造函数。
-
拷贝构造函数
#include "stdafx.h" #include "iostream.h" class Test { int i; int *p; public: Test(int ai,int value) { i = ai; p = new int(value); } ~Test() { delete p; } Test(const Test& t) { this->i = t.i; this->p = new int(*t.p); } }; //复制构造函数用于复制本类的对象 int main(int argc, char* argv[]) { Test t1(1,2); Test t2(t1);//将对象t1复制给t2。注意复制和赋值的概念不同 return 0; }赋值构造函数默认实现的是值拷贝(浅拷贝)。
-
移动构造函数。用于将其他类型的变量,隐式转换为本类对象。下面的转换构造函数,将int类型的r转换为Student类型的对象,对象的age为r,num为1004.
Student(int r) { int num=1004; int age= r; }
1.3.7 只定义析构函数,会自动生成哪些构造函数
参考答案
只定义了析构函数,编译器将自动为我们生成拷贝构造函数和默认构造函数。
默认构造函数和初始化构造函数。 在定义类的对象的时候,完成对象的初始化工作。
class Student
{
public:
//默认构造函数
Student()
{
num=1001;
age=18;
}
//初始化构造函数
Student(int n,int a):num(n),age(a){}
private:
int num;
int age;
};
int main()
{
//用默认构造函数初始化对象S1
Student s1;
//用初始化构造函数初始化对象S2
Student s2(1002,18);
return 0;
}
有了有参的构造了,编译器就不提供默认的构造函数。
拷贝构造函数
#include "stdafx.h"
#include "iostream.h"
class Test
{
int i;
int *p;
public:
Test(int ai,int value)
{
i = ai;
p = new int(value);
}
~Test()
{
delete p;
}
Test(const Test& t)
{
this->i = t.i;
this->p = new int(*t.p);
}
};
//复制构造函数用于复制本类的对象
int main(int argc, char* argv[])
{
Test t1(1,2);
Test t2(t1);//将对象t1复制给t2。注意复制和赋值的概念不同。
return 0;
}
赋值构造函数默认实现的是值拷贝(浅拷贝)。
答案解析
示例如下:
class HasPtr
{
public:
HasPtr(const string& s = string()) :ps(new string(s)), i(0) {}
~HasPtr() { delete ps; }
private:
string * ps;
int i;
};
如果类外面有这样一个函数:
HasPtr f(HasPtr hp)
{
HasPtr ret = hp;
///... 其他操作
return ret;
}
当函数执行完了之后,将会调用hp和ret的析构函数,将hp和ret的成员ps给delete掉,但是由于ret和hp指向了同一个对象,因此该对象的ps成员被delete了两次,这样产生一个未定义的错误,所以说,如果一个类定义了析构函数,那么它要定义自己的拷贝构造函数和默认构造函数。