Why does C ++ support a pure virtual function with implementation?

Today I did a simple test:

struct C{virtual void f()=0;};
void C::f(){printf("weird\n");}

The program is fine, but for me it is strange when we use it =0, it means that the body of the function must be defined in the inherited classes, but it looks like I can still give it an implementation function.

I tried both GCC and VC, both OK. Therefore, it seems to me that this should be part of the C ++ standard.

But why is this not a syntax error?

The reason I might think is similar to C # having both an “interface” and “abstract” keywords, an interface cannot have an implementation, while an abstract can have some implementations.

Is this the reason for my confusion that C ++ should support this kind of weird syntax?

+4
8

++ , , , .

:

class PersonBase
{
private:
    string name;
public:
    PersonBase(string nameIn) : name(nameIn) {} 

    virtual void printDetails() = 0
    {
        std::cout << "Person name " << name << endl;
    }
};

class Student : public PersonBase
{
private:
    int studentId;
public: 
    Student(string nameIn, int idIn) : PersonBase(nameIn), studentId(idIn) {  }
    virtual void printDetails()
    {
        PersonBase::printDetails(); // call base class function to prevent duplication
        std::cout << "StudentID " << studentId << endl;
    }
};
+3

, ( ...).

, - . , , , .

:

class Base {
public:
  virtual int f() = 0;
};
int Base::f() {
  return 42;
}

class Derived : public Base {
public:
  int f() override {
    return Base::f() * 2;
  }
};

, ...

- , , . .

class Base {
public:
  ~Base() = 0;
};
Base::~Base() { /* destruction... */ }
+2

, :

, , , , //. , . .

, . //, Base::f();
, , .

+2

. , , .

,

class Shape {
public:
    virtual Shape() {}

    virtual bool contains(int x, int y) const = 0;
    virtual int width() const = 0;
    virtual int height() const = 0;
    virtual int area() const = 0;
}

int Shape::area() const {
    int a = 0;
    for (int x = 0; x < width(); ++x) {
        for (int y = 0; y < height(); ++y) {
            if (contains(x,y)) a++;
        }
    }
    return a;
}

, . , ,

+1

, .

:

C c;

VC2015, , :

1>f:\dev\src\consoleapplication1\consoleapplication1.cpp(12): error C2259: 'C': cannot instantiate abstract class 
1>f:\dev\src\consoleapplication1\consoleapplication1.cpp(12): note: due to following members: 
1>f:\dev\src\consoleapplication1\consoleapplication1.cpp(12): note: 'void C::f(void)': is abstract 
1>f:\dev\src\consoleapplication1\consoleapplication1.cpp(6): note: see declaration of 'C::f'

: , , - . Baseclass (C), :

struct D : public C { virtual void f(); }; 
void D::f() { printf("Baseclass C::f(): "); C::f(); }
...
D d; 
d.f();
+1

" ".

:

struct A{ virtual void foo(){}; };
struct B:A{ virtual void foo()=0; };
struct C:B{ virtual void foo(){}; };
struct D:C{ virtual void foo()=0; };
void D::foo(){};
struct E:D{ virtual void foo(){D::foo();}; };

A foo.

B . .

C .

D .

E , D.

A, C E . B D .

, , , " ", .

- , , - . . , , . , , .

, . override , , , .

+1

, . , .

: , .

0

. , , , .

0

Source: https://habr.com/ru/post/1653990/


All Articles