【问题标题】:Can a derived class's member function behavior be determined by which class it is instantiated by?派生类的成员函数行为可以由它实例化的类来确定吗?
【发布时间】:2018-01-19 19:14:46
【问题描述】:

类 Rectangle 和 Triangle 都是从 Shape 派生的。我想添加另一个类 ComplexShape,它可以是附加了其他形状的任何特定形状。

我知道这个问题有一些简单的解决方法,比如声明一个变量来在基类中存储形状属性,但我对解决标题问题的方法更感兴趣。如果可能,如何定义 ComplexShape 的构造函数,以便 ComplexShape 使用用于初始化它的类的方法?

#include <iostream>
#include <memory>
#include <vector>

class Shape {
    public: virtual unsigned int getPointCount() const = 0;
};

class Rectangle : public Shape {
    public: unsigned int getPointCount() const { return 4; }
};

class Triangle : public Shape {
    public: unsigned int getPointCount() const { return 3; }
};

class ComplexShape : public Shape {
public:
    std::vector<std::shared_ptr<Shape>> children;

    //What Constructor comes here?

    unsigned int getPointCount() const {
        unsigned int i{ 0u };
        for(auto shape : children) i += shape->getPointCount();
        return i;
    }
};

int main() {
    Triangle triangle();
    ComplexShape arrow; //How do I initialize this as a rectangle?
    arrow.children.push_back(std::shared_ptr<Shape>(new Triangle()));
    std::cout << arrow.getPointCount();
    return 0;
};

【问题讨论】:

  • 您说复杂形状是形状的集合,为什么不这样实现呢?我认为没有必要像您要求的那样将其中一种形状“提升”为“基本”形状。
  • 回答标题中的问题:我认为没有。您可以将其实现为模板,然后您有一个强类型成员来引用“主要”形状。 (我是 C# 开发人员,如果我的措辞不正确,我深表歉意。我指的是 C# 泛型)
  • 搜索复合模式,它会给你一个如何实现它的想法。顺便说一句,你的变量ˋchildren` 应该是私有的。正如其他 cmets 所指出的,如果“主”形状在子列表中可能会更好。
  • 哎呀,我意识到我搞砸了。 ComplexShape::getPointCount 不应该只是孩子的点,也应该是父母的点。这让我意识到,由于 ComplexShape::getPointCount 与 Rectangle::getPointCount 不同,因此让 ComplexShape 成为 Rectangle 是没有意义的。我只是太封闭了。
  • Triangle triangle(); 那个三角函数在哪里定义的?

标签: c++ inheritance virtual-inheritance


【解决方案1】:

您可以尝试使用构造函数中使用的初始化列表:http://www.cplusplus.com/reference/initializer_list/initializer_list/

#include <iostream>
#include <memory>
#include <vector>
#include <initializer_list>

class Shape {
public: virtual unsigned int getPointCount() const = 0;
};

class Rectangle : public Shape {
public: unsigned int getPointCount() const { return 4; }
};

class Triangle : public Shape {
public: unsigned int getPointCount() const { return 3; }
};

class ComplexShape : public Shape {
public:
    std::vector<std::shared_ptr<Shape>> children;
    ComplexShape() {}

    ComplexShape(std::initializer_list<std::shared_ptr<Shape>> init) : children(init)
    {
        // do some dynamic_cast magic here
    }

    unsigned int getPointCount() const {
        unsigned int i{ 0u };
        for (auto shape : children) i += shape->getPointCount();
        return i;
    }
};

int main() {
    Triangle triangle();
    ComplexShape arrow; //How do I initialize this as a rectangle?
    arrow.children.push_back(std::shared_ptr<Shape>(new Triangle()));
    std::cout << arrow.getPointCount();

    // This could be simplified probably
    ComplexShape rect = { std::shared_ptr<Shape>(new Triangle()), std::shared_ptr<Shape>(new Triangle()) };
    return 0;
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-04
    • 2016-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多