C++ 对象间的赋值与拷贝构造函数

1、对象间的赋值

/***A.h文件***/
#pragma once
class A
{
public:
    int va;
    A(void);
    A(char* name);
    A(const A& a);
    virtual void print();
    char* name;
    void setVa(int va){
        this->va = va;
    }
public:
    ~A(void);
};
/****A.cpp文件******/
#include "StdAfx.h"
#include "A.h"
#include <iostream>

using namespace std;

A::A(void)
{
cout<< "a constructor is invoked .." << endl;
this->va = 5;
}

A::A(char* name)
{
this->name = name;
cout<< "constructor of object of Class A, whose name is " << name << " , is invoked .." << endl;
}


A::~A(void)
{
cout<< "a[name is "<< name <<"] is destroy .." << endl;

}

A::A(const A& a){
//cout<< "a[name="<< this->name <<"] copy constructor is invoked.." << endl;
cout<< "A copy constructor is invoked.." << endl;
this->name = a.name;
this->va = a.va;
}

 

void A::print(){
cout << "this is a" << endl;
}

 
#pragma once
#include "a.h"

class B :
    public A
{
 
public:
    int va;//在这里重新声明了va变量
    B(char* name4A);
    void print();
    static int i;    
public:
    ~B(void);
};
#include "StdAfx.h"
#include "B.h"
#include <iostream>
using namespace std;

B::B(char * name4A):A(name4A)
{
    this->setVa(10);
    cout<< "b constructor is invoked .." << endl;
    this->va = 3;
}

B::~B(void)
{
    cout<< "b is destroy .." << endl; 
}


void B::print(){
    cout << "this is B" << endl;
}

int B::i = -1;
// cplusplusprimer.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "A.h"
#include "B.h"
#include <iostream>
using namespace std;

static int i;
int j ;

int _tmain(int argc, _TCHAR* argv[])
{
    
    
    A a("aSelf");
    B b("aFromB");
    //A a1("aSelf1");
    
    cout<<"Hello C-Free!"<<endl;

    a.va = -1;
    b.va = -2;
    //a1.va = -3;
     

    cout<< "a.va=" <<a.va<<endl;
    cout<< "b.va=" <<b.va<<endl;

     
    cout<< "*************************************"  <<endl;

 
    a= b;
    
    a.name = "aSelf";
    
    //下面的这条命令
    //在这里你认为输出的值应该是什么呢
    //你是不是认为输出的应该是-2,但事实上呢输出的是10,为什么呢?(问题1)
    cout<<"a.va="<<a.va<<endl;
    
    cout<<"b.va="<<b.va<<endl; 

    a.print();


    
    cout<< "*************************************"  <<endl;


    /************************************************************************/
    /* 一般来说,变量(不管是普通变量,还是类成员变量)都需要初始化的,如果没初始化就使用了,可能会出现未知的错误
    /************************************************************************/
    cout<<"i="<<i<<endl;//静态变量系统会分配一个默认值给他
    cout<<"j="<<j<<endl;
    
    /*
    int q;
    cout<<"j="<<q<<endl;//因为没有进行初始化,所以这里出错了 
    */

    cout<<"b.i="<<b.i<<endl; 

    
    a.print();
    return 0;
}

关于以上面这段代码中注释里面提出的问题1,你能否解答呢.

在C++,每个类事实上都会默认对"="进行重写

operator=()

如果对一个类定义了两个或多个对象,则这些同类的对象之间可以互相赋值,或者说,一个对象的值可以赋给另一个同类的对象。这里所指的对象的值是指对象中所有数据成员的值。

对象之间的赋值也是通过赋值运算符“=”进行的。本来,赋值运算符“=”只能用来对单个的变量赋值,现在被扩展为两个同类对象之间的赋值,这是通过对赋值运算符的重载实现的。

实际这个过程是通过成员复制来完成的,即将一个对象的成员值一一复制给另一对象的对应成员。

对象赋值的一般形式为
   对象名1 = 对象名2;

注意对象名1和对象名2必须属于同一个类。例如
Student stud1,stud2; //定义两个同类的对象

stud2=stud1; //将stud1赋给stud2

通过下面的例子可以了解怎样进行对象的赋值。
例9.9 对象的赋值。
#include <iostream>
using namespace std;
class Box
{
   public :
   Box(int =10,int =10,int =10); //声明有默认参数的构造函数
   int volume( );
   private :
   int height;
   int width;
   int length;
};
Box::Box(int h,int w,int len)
{
   height=h;
   width=w;
   length=len;
}
int Box::volume( )
{
   return (height*width*length); //返回体积
}
int main( )
{
   Box box1(15,30,25),box2; //定义两个对象box1和box2
   cout<<″The volume of box1 is ″<<box1.volume( )<<endl;
   box2=box1; //将box1的值赋给box2
   cout<<″The volume of box2 is ″<<box2.volume( )<<endl; return 0;
}
运行结果如下:
The volume of box1 is 11250
The volume of box2 is 11250

说明:
(1) 对象的赋值只对其中的数据成员赋值,而不对成员函数赋值。
(2) 类的数据成员中不能包括动态分配的数据,否则在赋值时可能出现严重后果。


注:
1、如果是子类对象给父类对象赋值,那么子类对象只会把从父类那边继承过来的数据成员赋值给父类对象成员
的数据成员。
2、如果子类重写了父类的数据成员,例如该数据成员为member,那么子类对象将拥有两份member数据成员
这也解释了问题1那里输出的是10,而不是-2。当子类对象赋值给父类对象时,对于被重写了的数据成员如何赋值给父类对象对应的数据成员.
也就是子类对象要选择哪个数据成员给相对应的父类数据成员呢? 答案是:子类对象在构造时它同时也会构造一个父类对象x,这些对象x所对应的数据成员member
将被赋值给对应的父类对象的数据成员。




原文地址:https://www.cnblogs.com/silentjesse/p/3219033.html