C++之“生而不同”之构造函数

Posted 是小臻吖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++之“生而不同”之构造函数相关的知识,希望对你有一定的参考价值。

    嗨咯,欢迎来到小臻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++之“生而不同”之构造函数的主要内容,如果未能解决你的问题,请参考以下文章

C++之构造函数缺省构造函数

C++面试之 类string的构造函数拷贝构造函数和析构函数

C++学习摘要之二:构造函数和析构函数

c++之构造函数,析构函数(五千字长文详解!)

C++学习 之 类中的特殊函数和this指针

[ C++ ] C++类与对象之 类中6个默认成员函数