Как предотвратить вызов виртуальной функции в конструкторе или деструкторе? - PullRequest
0 голосов
/ 21 декабря 2010

В некоторых материалах C ++ упоминается, что мы не можем вызвать виртуальную функцию внутри ctor или dtor,

(
извините, я думаю, что лучше изменить на
В некоторых материалах C ++ упоминается, что нам лучше не вызывать виртуальную функцию внутри ctor или dtor,

)

но мы можем назвать их случайно. Есть ли способ предотвратить это?

Например:

# include < iostream >  
using namespace std;  

class CAT  
{  
public:  
    CAT(){ f();}  
    virtual void f(){cout<<"void CAT:f()"<<std::endl;}  
};  

class SMALLCAT :public CAT  
{  
public:  
    SMALLCAT():CAT()  
    {  
    }  
    void f(){cout<<"void SMALLCAT:f()"<<std::endl;}    
};    

int main()  
{  
    SMALLCAT sc;   

}  

выход:

void CAT::f()  //not we expected!!!

Спасибо

Ответы [ 3 ]

3 голосов
/ 21 декабря 2010

Вам нужно выбросить эти "материалы C ++" в мусорное ведро.

Вы, конечно, можете вызывать виртуальные функции из конструктора или деструктора. И они сделают свою работу. Вам просто нужно знать спецификацию языка, в которой четко указано, что механизм виртуальной диспетчеризации работает в соответствии с current динамическим типом объекта, а не с его final предполагаемым динамическим типом. Эти типы не одинаковы для строящегося / уничтожаемого объекта, что часто сбивает с толку новичков, когда они пытаются вызвать виртуальные функции из конструкторов / деструкторов. Тем не менее, вызов виртуальных функций из конструктора и деструктора является полезной функцией языка, если вы знаете, что они делают и как они работают в таких случаях. Почему вы хотите «предотвратить» это?

Это все равно что говорить, что оператор деления опасен, поскольку можно делить что-то на ноль, и спрашивать, как «предотвратить» его использование в программе.

0 голосов
/ 21 декабря 2010

Вы, конечно, можете вызывать виртуальную функцию внутри ctor / dtor. Проблема в том, что ваша vtable установлена ​​в каждом конструкторе (и деструкторе), поэтому ваш вызов виртуальной функции будет вызывать реализацию класса, который в данный момент настраивается. Если это то, что вы хотите, круто. Но тогда вы также можете сохранить себе поиск в vtable и выполнить вызов функции с ограничением.

0 голосов
/ 21 декабря 2010

Вы можете вызвать виртуальную функцию внутри деструктора.Только в определенных случаях это не сработает и может привести к сбою вашей программы.Чтобы не звонить им, нужно не звонить им.Я не знаю ничего более изворотливого, кроме, возможно, некоторых инструментов статического анализа, которые могут посмотреть на ваш код и предупредить вас о возможных проблемах, подобных этой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...