开发者

Why do I have to specify pure virtual functions in the declaration of a derived class in Visual C++?

开发者 https://www.devze.com 2022-12-27 03:37 出处:网络
Given the base class A and the derived class B: class A { public: virtual void f() = 0; }; class B : public A {

Given the base class A and the derived class B:

class A {
public:
  virtual void f() = 0;
};

class B : public A {
public:
  void g();
};

void B::g() {
    cout << "Yay!";
}

void B::f() 开发者_运维知识库{
    cout << "Argh!";
}

I get errors saying that f() is not declared in B while trying do define void B::f(). Do I have to declare f() explicitly in B? I think that if the interface changes I shouldn't have to correct the declarations in every single class deriving from it. Is there no way for B to get all the virtual functions' declarations from A automatically?

EDIT: I found an article that says the inheritance of pure virtual functions is dependent on the compiler: http://www.objectmentor.com/resources/articles/abcpvf.pdf

I'm using VC++2008, wonder if there's an option for this.


Do I have to declare f() explicitly in B?

Yes, you have to declare in the class' definition all virtual function of any base classes that you want to override in the class. As for why: That's just the way the C++ syntax is.
Note that the virtual keyword can be omitted for the declaration of overriding virtual functions:

class base {
  virtual void f();
  virtual void g();
};

class derived : public base {
  virtual void f(); // overrides base::f()
  void g();         // overrides base::g()
};

Note: A class declaration is this: class my_class;, while this class my_class { /* ... */ }; is a class definition. There's a limited number of things you can do with a class that's only been declared, but not defined. In particular, you cannot create instances of it or call member functions.
For more about the differences between declaration and definitions see here.

Ok, for the benefit of the "declaration vs. definition" debate happening in the comments, here is a quote from the C++03 standard, 3.1/2:

A declaration is a definition unless it [...] is a class name declaration [...].

3.1/3 then gives a few examples. Amongst them:

[Example: [...]
struct S { int a; int b; }; // defines S, S::a, and S::b
[...]
struct S; // declares S
—end example]

To sum it up: The C++ standard considers struct S; to be a declaration and struct S { /*...*/ }; a definition. I consider this a strong backup of my interpretation of "declaration vs. definition" for classes in C++.


Yes, in C++ you have to explicitly clarify your intention to override the behavior of a base class method by declaring (and defining) it in the derived class. If you try to provide a new implementation in derived class without declaring it in class definition it will be a compiler error.


The C++ class declaration defines the content of the class. If you do not declare f() in B, it looks like you do not override it. B::f() can be implemented only if you declare it.


In your current code, you are just inheriting the function f() in class B and you do not redefine base class's member in derived class.


Is there no way for B to get all the virtual functions' declarations from A automatically?

If you do not mark the function f in A as pure virtual with =0, the function is automatically also present in any subclass.

class A {
public:
  virtual void f(); // not =0!
};

class B : public A {
public:
  void g();
};

void A::f() {
    cout << "I am A::f!";
}

void B::g() {
    cout << "Yay!";
}

Now:

B* b = new B();
b->f(); // calls A::f


By declaring a pure virtual function you are stating that your class is abstract and that you want to require all concrete derived classes to have an implementation of that function. A derived class which does not supply an implementation for the pure virtual function is an extension of the abstract base class and is, itself, an abstract class. Trying to instantiate an abstract class is, of course, an error.

Pure virtual functions allow you to define an interface "contract" that you expect all derived classes to adhere to. A client of that class can expect that any instantiated class with that interface implements the functions in the contract.

Another interesting tidbit... you may supply a body for a pure virtual function but it is still pure and must be overridden in a concrete derived class. The advantage to supplying the body is to provide base behavior while still forcing derived classes to implement the function. The overridden functions can then call the base function Base::F() just like other virtual functions. When the body is not defined, calling Base::F() on a pure virtual functions is an error.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号