0623第七讲拷贝构造函数

0623第七讲拷贝构造函数
拷贝构造函数:
1、定义:通过一个已经存在的对象来创建新对象(构造函数参数是一个对象)Circle(const Circle &c);
2、拷贝构造函数调用情况
1)用一个对象初始化另一个对象

Classname object(otherObject);//拷贝构造函数
Classname object = otherObject;//拷贝构造函数

Classname object;
object = otherObject;//赋值运算符
2)函数以值传递的形式,实參赋值给形參,调用拷贝构造函数
void func(Person p);
func(object);

3)函数值返回形式返回一个对象,返回值会调用拷贝构造函数创建一个临时变量用来使用。
Person func(){
Person p;
return p;
}回去用vc测试一下

3、拷贝构造函数编写:
1)开辟新空间
2)赋值
Class(const &obj);
注意:拷贝构造函数参数必须是一个引用
如果拷贝构造函数的参数是以值传递的话,他本身执行时也需要穿參,而穿參时又要调用拷贝构造函数,2.1->2.2->2.1->……程序进入死循环。如果是传引用的方式的话就不会出现这个情况。
Person(Person& p)//ok
Person(Person p)//error
{…}
Person p1(p2);
如果成员变量包含指针,程序猿必须实现3个函数(拷贝构造函数、析构函数、赋值运算符重载函数)
构造函数和类型转换:当构造函数只有一个参数,可以自动将形參转换成对象
拷贝与构造:

Demo foo(Demo x){
 Demo d;//4.构造函数被调用
 return d;
 }
 int main(int argc, const char * argv[]) {
 Demo a(2);//1.构造函数被调用
 {
 Demo b;//2.构造函数被调用
 b=foo(a);//3.拷贝构造函数被调用
 //5.赋值运算符函数被调用
 }//6.析构函数被调用//7.析构函数被调用//8.析构函数被调用 析构x,d,b
 Demo c=a;//9.拷贝构造函数被调用
 //10.析构函数被调用//11.析构函数被调用  析构c,a
 return 0;
}

Person.hpp

#ifndef person_hpp
#define person_hpp
#include <stdio.h>
#include <iostream>
using namespace std;
class Person
{
    friend ostream& operator<<(ostream& out,const Person& p);
private:
    char *name;
    char sex[6];
    int age;
    char hobby[20];
public:
    Person(char* name);
    Person(const Person& p);
    ~Person();
    Person();
    Person(char *_name,char *_sex,int _age,char *_hobby);
    void setPerson(char *_name,char *_sex,int _age,char *_hobby);
    char* getName()const;
    void print();
    void setName(char *name);
    Person& operator=(Person& p);
};
#endif

Person.cpp

#include "person.hpp"
#include "iostream"
#include "string"
using namespace std;
char* Person:: getName()const
{
    return name;
}
Person::Person(char* _name)
{
    this->name=new char[strlen(_name)+1];
    strcpy(name, _name);
    cout<<"调用单个参数构造函数"<<endl;
}
Person::Person(const Person& p)
{
    this->name=new char[strlen(p.name)+1];
    strcpy(name, p.name);
    strcpy(sex, p.sex);
    age=p.age;
    strcpy(hobby, p.hobby);
    cout<<"调用拷贝构造函数"<<endl;
}
ostream& operator<<(ostream& out,const Person& p)
{
    out<<"姓名:\t" <<p.name<<"\t性别:\t"<<p.sex<<"\t年龄:\t"<<p.age<<"\t爱好:\t"<<p.hobby<<endl;
    return out;
}
Person& Person:: operator=(Person& p)
{
    if (this != &p) {
        delete [] this->name;
        this->name=NULL;
        name=new char [strlen(p.name)+1];
        strcpy(this->name ,p.name);
        strcpy(this->sex ,p.sex);
        this->age=p.age;
        strcpy(this->hobby ,p.hobby);
    }
    cout<<"调用重载的赋值运算符"<<endl;
    return *this;
}
Person::~Person()
{
    if (name!=NULL) {
        delete []name;
        name=NULL;
    }
    cout<<"调用Person析构函数"<<endl;
}
Person::Person()
{
    name=NULL;
//    strcpy(name, "");
//    strcpy(sex, "");
    age=0;
//    strcpy(hobby, "");
    cout<<"调用Person默认构造函数"<<endl;
}
Person::Person(char *_name,char *_sex,int _age,char *_hobby)
{
    name=new char[strlen(_name)+1];
    strcpy(name, _name);
    strcpy(sex, _sex);
    age=_age;
    strcpy(hobby, _hobby);
    cout<<"调用Person有參构造函数"<<endl;
}
void Person::setPerson(char *_name,char *_sex,int _age,char *_hobby)
{
    strcpy(name, _name);
    strcpy(sex, _sex);
    age=_age;
    strcpy(hobby, _hobby);
}
void Person::print()
{
    cout<<"姓名:\t" <<name<<"\t性别:\t"<<sex<<"\t年龄:\t"<<age<<"\t爱好:\t"<<hobby<<endl;
}
void Person::setName(char *name)
{
    strcpy(this->name, name);
    cout<<"设置name"<<endl;
}

main.cpp

#include <iostream>
using namespace std;
#include "person.hpp"
void print(const Person& p)
{
    cout<<"name = "<<p.getName()<<endl;
}
int main(int argc, const char * argv[]) {
    Person p1((char*)"jiji");//默认构造函数,把字符串转成临时对象
    print(p1);
    print((char*)"lily");//调用单个参数构造函数构造临时对象,函数结束释放
    Person p2=(char*)"lilei";
    print(p2);
    Person array[]={(char*)"caoqiang",(char*)"heyi",(char*)"yangyang",(char*)"zhangke",(char*)"peizhengmeng",(char*)"baoming"};
    for (int i=0; i<6; ++i) {
        print(array[i]);
    }
    return 0;
}

课堂练习
写一个Student类
属性:char *name ,int score ,char *label,int grade,char enjoy[20]
行为:默认构造函数、有參数的构造函数、拷贝构造函数、析构函数、输出运算符重载、赋值运算符重载
CStudent.hpp

#ifndef CStudent_hpp
#define CStudent_hpp

#include <stdio.h>
#include <iostream>
using namespace std;
class CStudent
{
    friend ostream& operator<<(ostream& out,const CStudent& s);

private:
    char* name;
    int score;
    char* label;
    int grade;
    char enjoy[20];
public:
//    CStudent();
    CStudent(char* _name=(char*)"",int _score = 0,char* _label=(char*)"",int _grade = 0,char* enjoy=(char*)"");
    CStudent(CStudent& s);
    ~CStudent();
    void operator=(CStudent& s);
};
#endif

CStudent.cpp

#include "CStudent.hpp"
#include <string>
using namespace std;
ostream& operator<<(ostream& out,const CStudent& s)
{
    out<<"调用重载输出运算符函数"<<endl;
    out<<"name = "<<s.name<<endl;
    out<<"score = "<<s.score<<endl;
    out<<"label = "<<s.label<<endl;
    out<<"grade = "<<s.grade<<endl;
    out<<"enjoy = "<<s.enjoy<<endl;
    return out;
}
//CStudent::CStudent(){
//    
//}
CStudent::CStudent (char* _name,int _score,char* _label,int _grade,char* _enjoy):score(_score),grade(_grade){
    name=new char[strlen(_name)+1];
    strcpy(name, _name);
    label=new char[strlen(_label)+1];
    strcpy(label, _label);
    strcpy(enjoy, _enjoy);
    cout<<"调用构造函数"<<endl;
}
CStudent::CStudent(CStudent& s){
    name=new char[strlen(s.name)+1];
    strcpy(name, s.name);
    label=new char[strlen(s.label)+1];
    strcpy(label, s.label);
    strcpy(enjoy, s.enjoy);
    score=s.score;
    grade=s.grade;
    cout<<"调用拷贝构造函数"<<endl;
}
CStudent::~CStudent(){
    if (name != NULL) {
        delete []name;
        name = NULL;
    }
    if (label != NULL) {
        delete []label;
        label = NULL;
    }
    cout<<"调用析构函数"<<endl;
}
void CStudent::operator=(CStudent& s){

        cout<<"调用重载赋值运算符函数"<<endl;
    if (this!=&s) {
        delete []name;
        name=NULL;
        delete []label;
        label=NULL;
        name = new char [strlen(s.name)+1];
        strcpy(name, s.name);
        label = new char [strlen(s.label)+1];
        strcpy(label, s.label);
        strcpy(enjoy, s.enjoy);
        score=s.score;
        grade=s.grade;
    }
}

main.cpp

#include <iostream>
#include "CStudent.hpp"
using namespace std;
CStudent func(CStudent _s)
{
    CStudent s=_s;
    return s;
}
int main(int argc, const char * argv[]) {
    CStudent s1((char*)"lily",100, (char*)"n",1, (char*)"study");
    CStudent s2(s1);
    //    cout<<"s1\n"<<s1<<"------------\n"<<"s2\n"<<s2<<endl;
    CStudent s3=s1;
    //    cout<<"s1\n"<<s1<<"s3\n"<<s3<<endl;
    CStudent s4;
    s4=s3;
    func(s4);
    cout<<"s3\n"<<s3<<"s4\n"<<s4<<endl;
}

输出结果:
调用构造函数
调用拷贝构造函数
调用拷贝构造函数
调用构造函数
调用重载赋值运算符函数
调用拷贝构造函数
调用拷贝构造函数
调用析构函数
调用析构函数
s3
调用重载输出运算符函数
name = lily
score = 100
label = n
grade = 1
enjoy = study
s4
调用重载输出运算符函数
name = lily
score = 100
label = n
grade = 1
enjoy = study

调用析构函数
调用析构函数
调用析构函数
调用析构函数
Program ended with exit code: 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值