Следующий код компилируется корректно, используя g ++ 6.3.0 с -Wall.
#include <iostream>
class Base
{
public:
Base(char const* base) : base_(base) {}
void print( char const* msg ) { print( base_, msg ); }
protected:
~Base() = default;
private:
char const* base_;
virtual void print( char const*, char const* ) = 0;
};
class Drv1 : public Base
{
public:
Drv1(char const* base, int i) : Base(base) , i_(i) {}
~Drv1() { std::cout << "Drv1 dtor" << std::endl; }
private:
int i_;
void print( char const* base, char const* msg ) override
{
std::cout << base << "(" << msg << "): " << i_ << std::endl;
}
};
class Drv2 : public Base
{
public:
Drv2(char const* base, double d) : Base(base) , d_(d) {}
~Drv2() { std::cout << "Drv2 dtor" << std::endl; }
private:
double d_;
void print( char const* base, char const* msg ) override
{
std::cout << base << "(" << msg << "): " << d_ << std::endl;
}
};
void do_test( char const* base, char const* msg, bool int_type )
{
Base&& _base(int_type ? (Base&&)Drv1(base, 1) : (Base&&)Drv2(base, 2.5));
_base.print( msg );
}
int main()
{
do_test( "Test1", "int", true );
do_test( "Test2", "double", false );
return 0;
}
Вывод при запуске следующий:
Drv1 dtor
Test1(int): 1
Drv2 dtor
Test2(double): 2.5
Вопросы:
Как это может быть определено поведение, если деструкторы производного класса были вызваны до вызова виртуальных функций?Если выходные данные на самом деле просто случайность, каковы параметры компилятора для решения этой проблемы?
Является ли rvalue reference
правильной терминологией для типа локальной переменной _base
вdo_test()
?Универсальные (или пересылаемые) ссылки встречаются в контексте шаблонов, но здесь нет шаблонов.