【问题标题】:How to have a parameter of an abstract data type?如何拥有抽象数据类型的参数?
【发布时间】:2016-03-18 21:25:15
【问题描述】:

我有一个名为 shape 的抽象类。

class Shape{
public:
    virtual const ColorRGB getColor() const;
    virtual double rayIntersectionDistance(Ray r) = 0;
};

现在我从 Shape 派生了以下类。

  1. class Sphere: public Shape { //implementation goes here }
  2. class Plane: public Shape { //implementation goes here }

我已经在这两个类中实现了 getColor()rayIntersectionDistance(Ray r) 方法,以及特定于这些类的其他方法。

所以现在,在另一个名为 Scene 的类中,我有一个 render() 方法,它的原型是:

void render(int width, int height, Shape s);

这似乎不起作用,编译器抱怨我说:

错误:不能将参数“s”声明为抽象类型“Shape”

我怎样才能做到这一点?有什么更好的方法来实现这一点?

【问题讨论】:

    标签: c++ class oop abstract


    【解决方案1】:

    通过值传递Shape 意味着传递Shape 的实例。但是Shape是抽象的,所以不能创建实例。

    改为传递指针或引用。 const 限定如果您不打算修改传递的对象(这也将阻止传递声明为 const 的对象,因为它们不应更改)。

     void func(Shape &s);    // define these functions as required
     void func2(Shape *s);
     void func3(const Shape &s);
    
     int main()
     {
            Sphere s;   // assumed non-abstract
    
            const Sphere s2;
    
            func(s);     // will work
            func2(&s);    // ditto
    
            func3(s);   // okay
            func3(s2);  // okay
    
            func(s);   // rejected, as s2 is const
     }
    

    编辑:

    正如 Barry 在 cmets 中提到的,也可以传递智能指针,例如 std::unique_pointer<Shape>std::shared_pointer<Shape> - 并且可以通过值传递。正如理查德霍奇斯所提到的,这在实践中是不寻常的,尽管这是可能的。事实上,任何管理指向Shape 的指针或引用的类型都可以被传递——假设它的构造函数(尤其是复制构造函数)实现了适当的行为。

    【讨论】:

    • func4(unique_ptr<Shape> ), func5(shared_ptr<Shape> ), ... ;-)
    • @barry 公平地说,将移动的 unique_ptr 传递给绘图函数是不寻常的。 @Peter 我可能不会鼓励func()func2()。太可恶了...func3() 就是一个。
    • @Barry - 是的。也可以传递包含指针或对Shape 的引用的任何类型——包括你提到的智能指针类型——只要该类型适当地管理其状态。
    • @Richard - 如果函数需要改变Shape 的状态,const 是不合适的。考虑一个RotateAboutOrigin(Shape &),它更新形状的定义点(顶点、中心等)的坐标——即使这是通过调用Shape 的非const 成员函数来完成的。那不能接受const
    • @Peter 在一般情况下你当然是对的。我想我在评论时仍然想到了操作问题。他给出的例子是非变异函数。
    猜你喜欢
    • 1970-01-01
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    相关资源
    最近更新 更多