详解C++构造函数
1.作用
一种特殊类型的方法,在每次实例化对象时运行
2.代码举例
2.1 示例1:
#include <iostream>
class A
{
public:
float a, b;
void print()
{
std::cout << a << " , " << b << std :: endl;
}
};
int main()
{
A a;
a.print();
return 1;
}
运行结果:
当我们实例化A,系统为它分配内存,我们没有初始化内存,得到的是内存空间原有的那些东西
2.2 示例2:
当在main中添加 std::cout << a.a << " , " << a.b << std :: endl;
int main()
{
A a;
std::cout << a.a << " , " << a.b << std :: endl;
a.print();
return 1;
}
(ubuntu下 vs code )
运行结果:
不同编译器可能不一样,有的会编译不过报错(未初始化局部变量),原因有待深入…
3. 使用
3.1 使用构造函数初始化
#include <iostream>
class A
{
public:
float a, b;
A ()
{
a = 0.0f;
b = 0.0f;
}
void print()
{
std::cout << a << " , " << b << std :: endl;
}
};
int main()
{
A a;
std::cout << a.a << " , " << a.b << std :: endl;
a.print();
return 1;
}
结果:
3.2 有参数的构造函数
#include <iostream>
class A
{
public:
float a, b;
// 无参构造
A ()
{
a = 0.0f;
b = 0.0f;
}
// 有参构造
A(float c,float d)
{
a = c;
b = d;
}
void print()
{
std::cout << a << " , " << b << std :: endl;
}
};
int main()
{
A a(5.0,6.0);
std::cout << a.a << " , " << a.b << std :: endl;
a.print();
return 1;
}
一个类可以有很多构造函数 前提是参数个数不同或者参数类型不同
类似于同名函数(函数重载 即有相同的函数名,但是有不同的参数个数与参数类型)
A(float c,float d)
{
}
A(int c,int d)
{
}
A(float c,float d,float e)
{
}
这里需要注意有参构造的时候注意传值类型
如 float
类型
A a(5.0f , 6.0f);
3.3 默认的构造函数
每个类默认有一个空参空实体的构造函数(如果写了构造函数,则默认构造函数就没有了,需要时需手动添加)
A ()
{
}
如果不想使用构造函数有两种方法
// 1 私有化
private :
A(){}
// 2 删掉
A() = delete;
4. 成员初始化列表
例1:正常初始化
#include <iostream>
using namespace std;
class Student
{
private:
const char *m_name;
int m_age;
float m_score;
public:
// 无参构造 给变量赋定值
Student()
{
m_name = "aaa";
m_age = 1;
m_score = 99.0;
}
// 有参构造 给变量动态赋值
Student(const char *name, int age, float score)
{
m_name = name;
m_age = age;
m_score = score;
}
void print ()
{
cout << m_name << " ," << m_age << " ," << m_score << endl;
}
};
int main(int argc, char const *argv[])
{
Student s1;
s1.print();
Student s2("ccc" , 2 , 99.3f);
s2.print();
return 0;
}
例2:成员初始化列表
#include <iostream>
#include <string>
using namespace std;
class Student
{
private:
// string m_name;
// char *m_name;
const char *m_name;
int m_age;
float m_score;
public:
// 无参 成员初始化列表
Student()
: m_name("bbb") , m_age(2) , m_score(93.0f)
{
// TODO
}
// 有参 成员初始化列表
Student(const char *name, int age, float score)
: m_name(name) , m_age(age) , m_score(score)
{
// TODO
}
void print ()
{
cout << m_name << " ," << m_age << " ," << m_score << endl;
}
};
int main(int argc, char const *argv[])
{
Student s1;
s1.print();
Student s2("ccc",2,99.3f);
s2.print();
return 0;
}
运行结果都一样:
aaa ,1 ,99
ccc ,2 ,99.3
使用构造函数初始化列表并没有效率上的优势,仅仅是书写方便,尤其是成员变量较多时,这种写法非常简单明了。
初始化列表可以用于全部成员变量,也可以只用于部分成员变量
Student(char *name, int age, float score): m_name(name){
m_age = age;
m_score = score;
}
NOTE:成员变量的初始化顺序与初始化列表中列出的变量的顺序无关,它只与成员变量在类中声明的顺序有关。
为啥推荐成员初始化列表的写法?
#include <iostream>
using namespace std;
class Example
{
public:
Example()
{
cout<< "Create Example" << endl;
}
Example(int x)
{
cout<< "Create Example with " << x << endl;
}
};
class A
{
private:
string m_name;
// 创建了 Example 的无参构造 对象
Example m_Example;
public:
A()
{
m_name = "name";
// 创建新的有参构造对象覆盖第一次赋值
m_Example = Example(1);
}
};
int main(int argc, char const *argv[])
{
A a;
return 0;
}
结果:
A的构造函数换成成员初始化列表的写法
// A() : m_name ("name"),m_Example(Example(1)) 与下面写法相同
A() : m_name ("name"),m_Example(1)
{
}
结果:
总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341