由基类创建派生类对象的说明(虚拟析构函数概念)

时间:2015-05-19 07:11:37

标签: c++ oop

我有两个班级:

ViewInjectionService

class A{ private: int a; public: void display() { cout<<"A: "<<a; } A() { a=10; } }; class B: public A { private: int b; public: void display1() { cout<<"B: "<<b; } B() { b=15; } }; A *a= new B之间有什么区别? 对象B *b = new B可以访问两个类bA的成员,而对象B只能访问A类成员。 但是在虚拟析构函数示例中给出:No Virtual constructors but virtual destructor或任何其他示例,它始终显示基类创建派生类的对象。为什么这会有用?当obj a只能访问a的成员时,需要创建class A的对象是什么?

我无法想到一个实际的例子。

4 个答案:

答案 0 :(得分:1)

  

我无法想到一个实际的例子。

它被称为多态,它可以说是OOP最重要的方面。基类可以使用虚函数定义接口;派生类可以覆盖这些函数以提供他们喜欢的任何行为。用户可以与基类进行交互,而不了解派生类,并且仍然使用派生类的功能。

要提供示例,只需更改基类以声明虚函数:

virtual void display() {cout << "A\n";}

并更改派生类以覆盖它,而不是使用不同的名称声明不相关的函数:

void display() override {cout << "B\n";}

现在我们可以看到A类对象之间的区别:

A a;
a.display();   // prints A

和B类型之一,即使通过指针或对A:

的引用访问
B b;
A & a = b;
a.display();   // prints B

答案 1 :(得分:1)

想象一下这个应用程序。你有一个形状类(基础)和两个矩形和trangle类(派生)。如何根据基类函数计算每个形状的面积。

class shape {
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b; }
    //look this method is virtual and is implemented in derived classes
    virtual int area () 
      { return 0; }
};

class Rectangle: public shape  {
  public:
    int area ()
      { return width * height; }
};

class Triangle: public shape  {
  public:
    int area ()
      { return (width * height / 2); }
};

使用

shape* s1 = new Rectangle();
shape* s2 = new Triangle();

//set values accordingly

然后你可以调用area函数,看看会调用哪些方法。 。

s1->area(); //area method of rectangle class
s2->area(); // area method of tangle class 

希望你明白了。

答案 2 :(得分:0)

这是外部访问的问题。虽然a允许其用户仅访问A的界面,但b允许其用户也可以访问B的界面。你似乎已经理解了这一部分。

您的第三个问题需要进行另一次比较:A *a = new B;A *a = new A;之间的区别是什么?这里的区别在于,在第一个例子中,a中的所有A个虚拟方法都被替换为&#34;由B提供。这称为专业化。当您使用超类A的更通用的接口时,运行时的实现是B用于虚拟方法。由于这些方法通常依赖于B的数据结构,因此必须实例化类B的对象。

答案 3 :(得分:0)

A* a = new B;

以及

B* b = new B;

在堆上创建一个对象。在第一种情况下,可以通过指针A访问a中定义的函数。如果A有任何virtual函数并且它们已在B中实现,那么在a上调用这些函数将最终调用B中的函数。 virtual上的任何非a函数调用都会调用A中定义的函数。

在第二种情况下,可以通过指针B访问A中定义的函数以及b中定义的函数。

在您的情况下,您可以使用:

a->display();

以及

b->display();

您可以使用

b->display1();

但你不能使用

a->display1();

如果您使用虚拟功能替换display()display1(),例如:

class A
{
   public:
      virtual display() { ... }
};

class B : public A 
 {
   public:
      virtual display() { ... }
};

然后,拨打

a->display();

最终会调用B::display()