繁体   English   中英

抽象类是否可以作为其他具体类的成员构成关系? C ++

[英]Can an abstract class be member of other concrete class as composition relationship ? c++

P是抽象类,我想使其成为A类的成员,而A类是普通的具体类。 如果可以,有可能吗。 关系是组成谢谢您的帮助

由于P是抽象的,因此您永远无法创建该类型的对象。 但是,您可以将指向P的指针存储为类A的成员; 然后,此指针成员可以指向P (具体)子类的实例。

否。组成关系意味着Client类实际上包含类型AbstractClass的成员变量。

我假设您对“抽象类”的定义是具有至少一个纯虚函数的类的常见定义。 这意味着它不能成为具体类的成员,因为该类不能被实例化。

您可以具有一个抽象类的引用或指针,该类包括一个为您管理生命周期的抽象类,例如组成关系,例如:

   class Client {
    public:
      Client(AbstractClass* adopted) : ownedAbstract(adopted) {}
    ...
    std::shared_ptr<AbstractClass> ownedAbstract;

   };

   class AbstractClass{
    public:
      virtual ~AbstractClass()=0;  // virtual dtor needed so can delete AbstractClass*    
   };       

   class AbstractSubclass : public AbstractClass{
    public:
      virtual ~AbstractSubclass();
   };


   Client fred(new AbstractSubclass);

您不能创建抽象类的任何对象。 所以你不能这样做。
但是,可以有一个指向抽象类的指针的类成员。

是一个代码示例,以证明这一点:

class abstract
{
   virtual void somethiing() = 0;
};

class concrete
{
    abstract obj;

};
int main()
{
    return 0;
}

汇编:

prog.cpp:8:错误:无法声明字段'concrete :: obj'为抽象类型'abstract'
prog.cpp:2:注意:因为以下虚拟函数在“抽象”中是纯函数:
prog.cpp:3:注意:虚空抽象:: somethiing()

编译样本:

class abstract
{
   virtual void somethiing() = 0;
};

class concrete
{
    abstract *ptr;

};
int main()
{
    return 0;
}

您不能在另一个类中显式实例化抽象类。 但是,您可以为抽象基类的纯虚函数提供一个定义,该定义又可以在派生类中以与组合非常相似的方式调用。

有效的C ++编程(第二版)表明,抽象类中的纯虚函数可以具有主体(定义)的原因是因为继承类可以提供在其主体内调用纯虚版本的函数的实现。

如果您有权使用该书,请参阅第36条。

这是我拼凑的一个例子。 它演示了如何通过从抽象类继承接口并使用其实现在派生类中构成函数定义的实现来实现一种对象组合形式。

#include <iostream>

class P {
  public:
    virtual void say_hello() = 0;
};

void P::say_hello() { std::cout << "Hello world!" << std::endl; }

class A :public P {
  public:
    void say_hello() { P::say_hello(); }
};

int main() {
    A x;
    x.say_hello();
    return 0;
}

结果将是类A的“ say_hello”将使用相同的名称调用P的函数的纯虚拟版本。 因此,调用A的“ say_hello()”将最终显示“ Hello world”。

抽象类中的公共和受保护成员数据也可用于派生类。

#include <iostream>
#include <string>

using namespace std;

class P {
  public:
    P() { audience = "world"; }
    virtual void say_hello() = 0;
  protected:
    string audience;
};

void P::say_hello() { cout << "Hello " << audience << "!" << endl; }

class A :public P {
  public:
    void say_hello() { P::say_hello(); }
    void say_goodbye() { cout << "Goodbye " << audience << "." << endl; }

};

int main() {
    A x;
    x.say_hello();
    x.say_goodbye();
    return 0;
}

我了解这听起来不对称,但答案是否定的。 抽象类无法实例化,因此不能用作另一个类的成员。

这种不对称是显而易见的,因为您可以将抽象类用作基类,甚至必须实例化对象的基类子对象。 但是在这种情况下,该操作是允许的,并且简单地将结果类自动变为抽象。

但是,合乎逻辑的原因是,在后一种情况下,您将能够从这个新的抽象类派生出一个具体的类,而在前一种情况下,C ++语言语法将无法用一个对象来替换一个包含的对象类型。从该类型派生的类。

从某种意义上说,可以稍后在继承层次结构中向下修改类的基础子对象的类型,而固定成员子对象的类型是固定的。

您当然可以在对象中使用指向抽象类的指针或引用,因为在这种情况下,对象的实际类型将是具体的,并且仅在运行时才知道。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM