C++之“生而不同”之构造函数
Posted 是小臻吖
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++之“生而不同”之构造函数相关的知识,希望对你有一定的参考价值。
嗨咯,欢迎来到小臻c++学习之路.话不多说,我们之间上车!!!
先来简单了解一下c++ 的结构趴
类的构成:方法和数据
类的设计
从他的结构不难看出,C++较c语言具有较好的封装性.
光说不练,我们来写一个人类 类
classHuman {
public: //公有的,对外的
void eat(); //方法,“成员函数”
void work();
string getName();
private:
string name;
};
void Human::eat() {
cout << "吃炸鸡,喝啤酒!" << endl;
}
void Human::work() {
cout << "我在工作..." << endl;
}
string Human::getName() {
return name;
}
int main(void) {
Human zhangshan;
system("pause");
}
好了,介绍就告一段落,下面我们言归正传,开始学习“生而不同”之构造函数.
构造函数一共有四种:
合成构造函数. 自定义的构造函数.拷贝构造函数.赋值构造函数.
下面我们来一一学习
1.1 构造函数
1.1.1合成构造函数
这个就比较简单了,在你什么都不写时,系统就会给你自动定义一个构造函数,就叫合成构造函数,在用类创建对象的时候就会先执行构造函数.
1.1.2自定义的构造函数
以Human类作演示
格式: Human();
Human::Human(){}
1.2自定义的重载构造函数
就如java的重载函数差不多,在自定义的构造函数中加若干参数
例如:Human(int age, int salary);
Human :: Human(int age, int salary);
1.3拷贝构造函数
这个也分自动的与手动的,自动的就是简单的复制粘贴道理与合成的构造函数相同,属于浅拷贝.
如: Human f1;
Human f2=f1;
首先我们来了解如何定义
如: Human(const Human &other)
Human :: Human (const Human &other)
Human(const Human &other)
Human::Human(const Human& other) {
this->age = age; //this是一个特殊的指针,指向这个对象本身
this->salary = salary;
}
那么现在有些小伙伴可能会问了,系统自带的不是挺好的,为什么要自己写呢,原因就在于这个浅拷贝.
首先先申明两个函数:
const char* getAddr();
void setAddr(const char* newAddr);
下面是API:
void Human::setAddr(const char* newAddr) {
if (!newAddr) {
return;
}
strcpy_s(Addr, 64, newAddr);
}
const char* Human::getAddr() {
return Addr;
}
Human::Human(const Human& other) {
this->age = age; //this是一个特殊的指针,指向这个对象本身
this->salary = salary;
strcpy_s(Addr, 64, newAddr);
}
我们再在main 方法中测试:
下面是拷贝构造函数的调用时机:
1 调用函数时,实参是对象,形参不是引用类型
如果函数的形参是引用类型,就不会调用拷贝构造函数
2 函数的返回类型是类,而且不是引用类型
3 对象数组的初始化列表中,使用对象。
1.4赋值构造函数
Human f1 ,f2;
f2 =f1;
注意与拷贝构造函数相区别哦
这个是有两个类,让两个类相同,上面的是创建一个与之前相同的类
下面我们上定义:
Human& operator=(constHuman &);
Human& Human::operator=(constHuman &man) {}
其本质就是=号的运算符重载,所以也有自动与手动,也有浅拷贝与深拷贝的区别,就不再作赘述了.直接上demo自己体会
#include<iostream>
#include<Windows.h>
#include<string>
#include<string.h>
usingnamespace std;
// 定义一个“人类”
classHuman {
public:
Human();
Human(intage, intsalary);
Human(constHuman&); //不定义拷贝构造函数,编译器会生成“合成的拷贝构造函数”
Human& operator=(constHuman &);
void eat();
void sleep();
void play();
void work();
string getName();
int getAge();
int getSalary();
void setAddr(constchar *newAddr);
constchar* getAddr();
private:
string name = "Unknown";
int age = 28;
int salary;
char *addr;
};
Human::Human() {
name ="无名氏";
age = 18;
salary =30000;
}
Human::Human(intage, intsalary) {
cout <<"调用自定义的构造函数"<< endl;
this->age = age; //this是一个特殊的指针,指向这个对象本身
this->salary = salary;
name ="无名";
addr = newchar[64];
strcpy_s(addr,64, "China");
}
Human::Human(constHuman &man) {
cout <<"调用自定义的拷贝构造函数"<<"参数:"<< &man
<<" 本对象:"<<this<< endl;
age = man.age; //this是一个特殊的指针,指向这个对象本身
salary = man.salary;
name =man.name;
// 深度拷贝
addr = newchar[64];
strcpy_s(addr,64, man.addr);
}
Human& Human::operator=(constHuman &man) {
cout<<"调用"<<__FUNCTION__<< endl;
if (this == &man) {
return *this; //检测是不是对自己赋值:比如 h1 = h1;
}
//如果有必要,需要先释放自己的资源(动态内存)
//deleteaddr;
//addr= new char[ADDR_LEN];
//深拷贝
strcpy_s(addr,ADDR_LEN, other.addr);
// 处理其他数据成员
name=man.name;
age= man.age;
salary= man.salary;
// 返回该对象本身的引用,以便做链式连续处理,比如 a = b = c;
return *this;
}
voidHuman::eat() {
cout <<"吃炸鸡,喝啤酒!"<< endl;
}
voidHuman::sleep() {
cout <<"我正在睡觉!"<< endl;
}
voidHuman::play() {
cout <<"我在唱歌! "<< endl;
}
voidHuman::work() {
cout <<"我在工作..."<< endl;
}
stringHuman::getName() {
return name;
}
intHuman::getAge() {
return age;
}
intHuman::getSalary() {
return salary;
}
voidHuman::setAddr(constchar *newAddr) {
if (!newAddr) {
return;
}
strcpy_s(addr,64, newAddr);
}
constchar* Human::getAddr() {
return addr;
}
void test(Humanman) {
cout <<man.getSalary() << endl;
}
void test2(Human &man) { //不会调用拷贝构造函数,此时没有没有构造新的对象
cout <<man.getSalary() << endl;
}
Human test3(Human &man) {
returnman;
}
Human& test4(Human &man) {
returnman;
}
int main(void) {
Human h1(25, 35000); // 调用默认构造函数
// 特别注意,此时是创建对象h2并进行初始化,调用的是拷贝构造函数,
// 不会调用赋值构造函数
Human h2 = h1;
h2 = h1; //调用赋值构造函数
h2 = test3(h1); //调用赋值构造函数
Human h3 = test3(h1); //调用拷贝构造函数
system("pause");
return 0;
}
ps :const 相当于只读属性,主要用于安全性.
千里之行,始于足下,先恭喜我们成功迈出了第一步了呦
今天就先到这里咯,我们下次再见!晚安
以上是关于C++之“生而不同”之构造函数的主要内容,如果未能解决你的问题,请参考以下文章