C ++:使用父类运算符函数更新子类对象的继承变量

Posted

技术标签:

【中文标题】C ++:使用父类运算符函数更新子类对象的继承变量【英文标题】:C++: Using parent class operator function to update inherited variables of a child class object 【发布时间】:2017-02-05 11:37:30 【问题描述】:

为了简化我的疑问,我编写了一些突出显示相同问题的虚拟代码。

所以,我有一个名为 Box 的类,它具有 + 运算符的重载。接下来,声明一个名为 Cube 的类,它继承自 Box 类。我希望能够使用 Box 类中定义的 + 重载。这对我来说似乎是合理的,因为任何 Cube 对象也是 Box 对象,并且继承的变量应该可以从继承的函数中配置。当前的问题在于 + 运算符返回一个不能转换为 Cube 对象的 Box 对象。但我无法使用 *this 是 Cube 对象的信息。

示例代码:

#include <iostream>
using namespace std;

class Box 
   double length, breadth, height;

public:
   Box();
   Box(double l, double b, double h)
      length=l;breadth=b;height=h;
   
   double getVolume() 
      return length * breadth * height;
   
   // Overload + operator to add two Box objects.
   Box operator+(const Box& b) 
      Box box;
      box.length = this->length + b.length;
      box.breadth = this->breadth + b.breadth;
      box.height = this->height + b.height;
      return box;
   
;

class Cube: public Box 
public:
   Cube();
   Cube(double size):Box(size,size,size)
   Cube operator+(const Cube& b) 
        return (Box(*this)+b);   // this is wrong
   
;

// Main function for the program
int main( ) 
   Cube C1(5),C2(10),C3; 
   C3=C1+C2;
   cout << "Volume of C3 : " << C3.getVolume() <<endl;
   return 0;

我已经阅读了很多关于这个主题的答案。 This 可能是最接近这个问题的。但是接受的答案会将 Cube 对象转换为 Box 对象,这在以后的部分中是不受欢迎的。

编辑:社区中的许多人都发现这个问题不清楚。 (我很抱歉。但这是我在堆栈上的第一个问题)。请不要看重载函数中发生的事情。这个想法是我不想将 Box 类中 + 运算符的内容复制到 Cube 类的 + 运算符中。我需要 Box 类的 + 运算符返回一个 Box 对象,以及 Cube 类上的 + 运算符,其中包括对继承变量执行 Box + 操作,并返回一个 Cube 类对象。

【问题讨论】:

【参考方案1】:

Cube 继承了 Box 的 operator+。您无需在 Cube 中再次实现它。 但是当删除 Cube operator+ 时,你会注意到 C3 = C1 + C2; 给出了一个错误。 C1 + C2 生成一个 Box 类型,您希望将其分配给 Cube 类型。她你应该问自己一个问题:C3 应该是 Cube 类型吗?如果你添加两个立方体,你会得到另一个立方体吗?我不这么认为。所以C3应该是Box-type。然后代码对我有用。

p.s.您也不需要 this->[成员变量]。您已经可以访问私有成员变量,因为您将 operator+ 定义为成员函数。

编辑:只是为了添加工作代码

#include <iostream>

class Box

private:
    double length;
    double breadth; // ?? do you mean "width"?
    double height;

public:
    Box() 
    Box(const double l, const double b, const double h)
        : length(l)
        , breadth(b)
        , height(h)
    

    // I don't know why the members are private? But you need access to check for a cube.
    double getLength() const  return length; 
    double getBreadth() const  return breadth; 
    double getHeight() const  return height; 

    double getVolume() const
    
        return length * breadth * height;
    

    // Overload + operator to add two Box objects.
    Box operator+(const Box& b)
    
        return Box (
            length + b.length,
            breadth + b.breadth,
            height + b.height);
    
;

class Cube : public Box

public:
    Cube(const double size = 0)
        :Box(size, size, size)
    

    Cube(const Box& b)
        : Cube(b.getLength())
    
        if ((b.getLength() != b.getBreadth()) || (b.getLength() != b.getHeight()))
            throw std::invalid_argument("Box is not a Cube!");
    
;

// Main function for the program
int main() 
    Cube C1(5), C2(10), C3;
    C3 = (C1 + C2);
    std::cout << "Volume of C3 : " << C3.getVolume() << std::endl;
    int temp;
    std::cin >> temp;
    return 0;

【讨论】:

很抱歉,我无法想出一个很好的例子来解释我的要求。请阅读我添加的编辑附件。我需要 C3 是立方体类型。 那么你应该在我的答案后面加上 xaxxon 的答案,所以实现一个接受框输入的立方体构造函数。并实现检查输入框是否为有效立方体的逻辑。 由于您还没有将任何内容标记为“最佳答案”,我猜您要么仍在苦苦挣扎(或机会主义者;)),所以我添加了一些适合我的代码。跨度> 是的。我仍然有点挣扎。我看到您已经重载了 = 运算符。但是通过构造函数将盒子转换为立方体对我来说看起来更普遍。一旦我能够将它实现到我的代码中,我将接受它作为答案,因为我可能需要进一步澄清这个主题。 (此代码只是一个类比)非常感谢您的帮助! 而且如果你仔细看代码,你可以证明两个立方体的总和永远是一个立方体;)【参考方案2】:

如果您添加一个接受 Box 的 Cube 构造函数,那么代码将起作用:

Cube(Box const &);

从现在开始,编译器可以将Box 隐式转换为Cube

直播:https://godbolt.org/g/JMAuz2

当然,您需要在新的构造函数中添加一些逻辑,以确保盒子实际上是一个立方体 - 如果不是,可能会抛出异常。

【讨论】:

【参考方案3】:

我不知道你面临什么问题,因为你的问题很不清楚。但是,我认为这就是你想要的。希望这会有所帮助

#include <iostream>
using namespace std;

class Box 
public:
double length, breadth, height;
Box()
Box(double l, double b, double h) 
    length = l; breadth = b; height = h;

double getVolume() 
    return length * breadth * height;

// Overload + operator to add two Box objects.
Box operator+(const Box& b) 
    Box box;
    box.length = this->length + b.length;
    box.breadth = this->breadth + b.breadth;
    box.height = this->height + b.height;
    return box;

;

class Cube : public Box 
public:
Cube()
Cube(double size) :Box(size, size, size) 
Cube operator+(const Cube& b) 
    Box b1(this->length, this->breadth,this>height),b2(b.length,b.breadth,b.height),b3;
    Cube t(this->breadth);
    b3 = b1 + b2;
    t.length = b3.length;
    t.breadth = b3.breadth;
    t.height = b3.height;
    return (t);  

;

// Main function for the program
int main() 
  Cube C1(5), C2(10), C3;
  C3 = C1 + C2;
  cout << "Volume of C3 : " << C3.getVolume() << endl;
  return 0;
 

【讨论】:

那么你的编译器让你编译错误的代码。这一行是错误的Box b1(this-&gt;length,this-&gt;breadth,this&gt;height),b2(b.length,b.breadth,b.height),b3; 注意第三个单词“this”。你有this&gt;height,而不是this-&gt;height。你应该对编译器标志做一些研究

以上是关于C ++:使用父类运算符函数更新子类对象的继承变量的主要内容,如果未能解决你的问题,请参考以下文章

C++--被遗弃的多重继承经典问题

重写和重载的区别

第六章动手动脑

第54课 被遗弃的多重继承(下)

有继承关系的对象执行顺序,包括静态变量,静态代码块,普通变量,普通代码块,继承方法.

java学习之继承之子父类中变量的特点