如何使用虚函数对Base类进行抽象?

时间:2011-09-08 08:37:37

标签: c++ inheritance virtual-functions

我有以下结构

class Base
{
public:
    Base(Type);
    virtual render
}

class A
{
public:
    Base(Type == A);
    void render()
}

class B
{
public:
    Base(Type == B);
    void render()
}

void client_function()
{
    Base baseObject(A);
    //Base is an instance of class A
    baseObject.render()//runs class A render
}

据我所知,上述代码中有些东西不是c ++,它们与Haskell中的模式匹配密切相关,但这是我能找到的最好的方法来说明我的问题而不知道答案;)

在编写中我希望客户端能够创建一个基础对象并将对象类型作为参数传递,返回对象的正确规范,客户端不需要关心它,只知道运行渲染将运行正确的特定渲染。

如果我不清楚,请随时提问:)

4 个答案:

答案 0 :(得分:3)

答案 1 :(得分:2)

您需要运行时多态。构造函数没有太多重要的部分。您必须将Base继承到AB。例如:

class Base
{
public:
  virtual void render ();  // <--- declare 'virtual'
  virtual ~Base();  // <--- very much needed to avoid undefined behavior
};
class A : public Base //<---- inheritance
{
public:
  void render();  // <--- this also becomes 'virtual'
};
...

现在您可以根据您的要求使用。

Base *baseObject = new A();  // <----- need to use pointer (or reference)
(*baseObject).render();  // <--- other way to write: baseObject->render();
delete baseObject;

答案 2 :(得分:1)

我不确定我理解你的问题。在C ++中,您无法在运行时选择基类,但您当然可以让您的基类依赖于派生类。这是通过使用模板和所谓的Curiously Recurring Template Pattern

来完成的
template <typename T> class Base {
public:
    virtual void render(T *) {}
};

class A : public Base<A>
{
public:
    void render(A * t) {}
};

class B : public Base<B>
{
public:
    void render(B * t) {}
};

void client_function() {
    A a1;
    A a2;
    a1.render(&a2); // calls A::render
    a1.Base<A>::render(&a2); // calls Base<A>::render
    Base<A> * ba = &a1;
    ba->render(&a2); // calls A::render
}

希望这能回答你的问题。

答案 3 :(得分:0)

你要求的正是继承的目的:从专门化功能的类层次结构创建对象。

在您的示例中,除了语法问题之外,事情将按预期工作,即方法A::render将被调用,即使您在编译时不知道该对象,也声明为{{1}确实是Base。这是虚拟继承的魔力。