Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;-将派生类的对象复制到基类的对象_C++_Inheritance - Fatal编程技术网

C++ C++;-将派生类的对象复制到基类的对象

C++ C++;-将派生类的对象复制到基类的对象,c++,inheritance,C++,Inheritance,由于重载运算符=的限制,我们无法将派生对象复制到基类的对象中。那么,为什么我们可以将派生对象的地址复制到基类的指针中呢?因为派生对象的大小比基类对象大,所以它不应该是另一种情况吗。事实上,当我尝试它时,我得到了一个错误,即不允许将基本对象转换为派生对象。你能告诉我为什么吗?我在网上找不到任何相关信息。 代码如下:- #include<string> #include<vector> #include<iostream> using namespace std;

由于重载运算符
=
的限制,我们无法将派生对象复制到基类的对象中。那么,为什么我们可以将派生对象的地址复制到基类的指针中呢?因为派生对象的大小比基类对象大,所以它不应该是另一种情况吗。事实上,当我尝试它时,我得到了一个错误,即不允许将基本对象转换为派生对象。你能告诉我为什么吗?我在网上找不到任何相关信息。 代码如下:-

#include<string>
#include<vector>
#include<iostream>
using namespace std;
class employee
{
    protected:
        string name;
        double pay;
    public:
        employee(string ename,double payRate)
        {
            name = ename;
            pay = payRate;
        }
        virtual double GrossPay(int days)
        {
            return pay*days;
        }
        virtual string getName()
        {
            return name;
        }
};
class manager:public employee
{
    private:
        bool salaried;
    public:
        manager(string ename,double payRate,bool isSalaried):employee(ename,payRate)
        {
            salaried = isSalaried;
        }
        virtual double GrossPay(int days)
        {
            if(salaried)
                return pay;
            else
                return pay*days;
        }
};
int main(void)
{
    employee* emp2;
    employee emp3("Bill",350);
    manager mgr3("Alice",200,true);
    emp2 = &emp3;
    cout<<emp2->getName()<<" earns "<<emp2->GrossPay(40)<<endl;
    emp2 = &mgr3;
    cout<<emp2->getName()<<" earns "<<emp2->GrossPay(40)<<endl; // The code works till here
    //The problematic part starts from here:- 
    manager* mgr6;                                          
    employee emp5("NewBill",300);
    mgr6 = &emp5;
    cout<<mgr6->getName()<<" earns "<<mgr6->GrossPay(40)<<endl;
    return 0;
}
#包括
#包括
#包括
使用名称空间std;
班级员工
{
受保护的:
字符串名;
双薪;
公众:
员工(字符串名称,双倍工资率)
{
name=ename;
工资=工资率;
}
虚拟双倍总收入(整数天)
{
返回工资*天;
}
虚拟字符串getName()
{
返回名称;
}
};
班级经理:公职人员
{
私人:
受薪工人;
公众:
经理(字符串ename,双倍工资率,布尔isSalaried):员工(ename,工资率)
{
有薪=有薪;
}
虚拟双倍总收入(整数天)
{
如果(受薪)
报酬;
其他的
返回工资*天;
}
};
内部主(空)
{
雇员*emp2;
雇员emp3(“法案”,350);
经理3(“Alice”,200岁,真实);
emp2=&emp3;

cout您无法将基础对象转换为派生对象,因为没有足够的信息。这就像拥有一个空三明治并假装它是BLT

向下转换对象的问题是,派生类可能更大,因此无法放入可用内存,但允许使用指针,因为派生类与基类完全相同,而且更多。继续三明治隐喻:如果忽略填充,BLT只是一个空三明治


在您的示例中,
mgr6
认为它指向的是一个
manager
,但假设有一个名为
bool salaried
的getter调用
IsSalaried()
当您调用
mgr6->IsSalaried()时会发生什么
。这显然是不符合逻辑的,因此是不允许的。

因为没有足够的信息,所以不能将基本对象转换为派生对象。这就像有一个空三明治,假装它是BLT

向下转换对象的问题是,派生类可能更大,因此无法放入可用内存,但允许使用指针,因为派生类与基类完全相同,而且更多。继续三明治隐喻:如果忽略填充,BLT只是一个空三明治


在您的示例中,
mgr6
认为它指向的是一个
manager
,但假设有一个名为
bool salaried
的getter调用
IsSalaried()
当您调用
mgr6->IsSalaried()时会发生什么
。这显然是不符合逻辑的,因此是不允许的。

继承关系通常被描述为“是A”,例如,如果您有一个基本类vehicle和两个派生类MotorCycle和Semi-then

  Motorcycle *m = new Motorcycle();
  Semi *s = new Semi();

  Vehicle *v1 = m;
  Vehicle *v2 = s;
很好。摩托车是一辆车,半挂车是一辆车。 您可以在v1和v2上调用任何想要的方法,并且将有该方法的实现

另一方面,如果你接着说:

  Motorcycle m2 = v2;
你会有麻烦的。这辆车不一定是摩托车

假设Motorcycle类有一个名为wheelie()的方法,该方法不在Vehicle类中(出于明显的原因),在该赋值之后,您可以说: M2->wheelie()


你可怜的semi不知道怎么做。因此,从基类到派生类的转换是不合法的。

继承关系通常被描述为“是A”,例如,如果你有一个基类vehicle和两个派生类MotorCycle和semi,那么

  Motorcycle *m = new Motorcycle();
  Semi *s = new Semi();

  Vehicle *v1 = m;
  Vehicle *v2 = s;
manager* mgr6;                                          
employee emp5("NewBill",300);
mgr6 = &emp5;
很好。摩托车是一辆车,半挂车是一辆车。 您可以在v1和v2上调用任何想要的方法,并且将有该方法的实现

另一方面,如果你接着说:

  Motorcycle m2 = v2;
你会有麻烦的。这辆车不一定是摩托车

假设Motorcycle类有一个名为wheelie()的方法,该方法不在Vehicle类中(出于明显的原因),在该赋值之后,您可以说: M2->wheelie()

你可怜的半成品不知道怎么做。因此,从基类到派生类的转换是不合法的

manager* mgr6;                                          
employee emp5("NewBill",300);
mgr6 = &emp5;
在您的示例中,
manager
类是从
employee
类派生的。因此,
emp5
是一个基类对象。它不知道派生的类成员

mgr6
属于
manager*
类型,它试图指向
emp5
。如前所述,
emp5
没有用于分配操作的派生类子对象

然而,这是可行的

employee* emp2;
manager mgr3("Alice",200,true);
emp2 = &mgr3;
因为,
mgr3
同时具有派生子对象和基类子对象

编辑:将最后一行中的emp3更正为mgr3

在您的示例中,
manager
类是从
employee
类派生的。因此,
emp5
是一个基类对象。它不知道派生的类成员

mgr6
属于
manager*
类型,它试图指向
emp5
。如前所述,
emp5
没有用于分配操作的派生类子对象

然而,这是可行的

employee* emp2;
manager mgr3("Alice",200,true);
emp2 = &mgr3;
因为,
mgr3
同时具有派生子对象和基类子对象


编辑:在最后一行将emp3更正为mgr3

我不确定我是否正确理解了您的意思。您可以执行-
Base obj=Derived();
。但是,对象已被切片。请发布您尝试的测试程序。您是否询问