2017-02-01 9 views
4

рассмотрит следующий код:Чистых виртуальный деструктор локального абстрактного класса

struct A { 
    virtual void foo() {} 
    virtual ~A() = 0; 
}; 
struct B :public A 
{ 
    virtual void foo() {}; 
}; 
A::~A() {}; 
int main() 
{ 
    A * a = new B(); 
    a->foo(); 
} 

это работает прекрасно. но теперь рассмотрим второй код, где нам нужно объявить наши классы локально внутри функции как:

void foo() 
{ 
    struct A { 
     virtual void foo() {} 
     virtual ~A() = 0; 
    }; 
    struct B :public A 
    { 
     virtual void foo() {}; 
    }; 
    A::~A() {}; //error C2352 : 'A::~A' : illegal call of non - static member function 

    A * a = new B(); 
    a->foo(); 
} 
int main() 
{ 
    foo(); 
} 

код не компилируется! Есть идеи? - это любой способ переопределить чистый виртуальный деструктор базового класса, который объявлен локально?

+2

Все определения метода локального класса должны быть встроены внутри класса. – Jarod42

+0

Поскольку вы находитесь в локальной области (поэтому вы управляете зависимостями), вы можете избавиться от '= 0' и предоставить код напрямую. – Jarod42

ответ

6

cppreference говорит

Объявление класса может появиться (...), так и внутри тела функции, в этом случае она определяет локальный класс

...

членов функции локального класса должны быть полностью определены внутри тела класса

4

Невозможно делать то, что вы хотите. Но также, подумайте об этом: почему вы обычно хотите дать определение тела для чистого виртуального деструктора? Типичным ответом является то, что вы хотите сделать класс абстрактным, но не имеете других методов, которые могут быть сделаны виртуальными. Сценарий, в котором это возникает, обычно находится там, где у вас нет прямого контроля над использованием или наследованием вашего класса. Но этого никогда не может быть для класса, определенного локально внутри функции: любое его использование по определению должно быть в пределах одного и того же тела функции, предоставляя автору полный контроль над использованием. Например, вы можете убедиться, что ваш класс всегда унаследован, а не используется как-есть (т. Е. Цель принуждения класса к абстрактному) просто, соблюдая это правило самостоятельно в прямом контролируемом контексте локальной функции.

1

В C++ вы не можете иметь вложенные функции. Делая

foo(){ 
//... 
A::~A{} // you define a nested function which is not allowed 
//... 
} 

ИМО, для вложенного класса с функцией, мы должны определить все, не чистые функции в классе блока.

Если вы хотите, чтобы ваш класс A был абстрактным классом, вы можете объявить A :: foo() как чистый виртуальный или несколько новых пустых функций. В любом случае вам нужно определить виртуальный dtor вне или внутри класса, так как это не приведет к ошибке связывания.

 Смежные вопросы

  • Нет связанных вопросов^_^