2014-11-15 4 views
1

Может ли полиморфизм использоваться для статического члена данных класса C++ (переменная класса a.k.a.)?Полиморфизм на статическом элементе данных класса C++

Обновление: Как указано в b4hand, полиморфные методы должны быть объявлены в базовом классе. Но это невозможно в этом случае, потому что заранее неизвестно, какие методы пользователь создаст в контейнере.

Я отредактировал пример, чтобы включить ссылки; Спасибо, что напомнили.

Вот моя попытка инициализировать статический базовый тип (numBase) к производному типу (кол-во):

#include <iostream> 

class numBase     //numBase is in a library user can not edit 
{ 
}; 

class numDer : public numBase //user defined class is a kind of numBase 
{ 
    private: 
     int num; 
    public: 
     void printNum() { std::cout << " numDer=" << num; } 
     void inc() { num++; } 
}; 

class containerBase    //containerBase is in a library user can not edit 
{ 
    protected: 
     //static numDer& count; //this compiles, but count can not be initialized to other types 
     static numBase& count; //this causes error six lines down from here 
}; 

class containerDerived : public containerBase //user defined class is a kind of containerBase 
{ 
    public: 
     void inc() { count.inc(); } //error: 'count' was not declared in this scope 
     void printCount() { std::cout << " containerDerived"; count.printNum(); } 
}; 

/************************ user program **********************/ 
//initilialize static variable 
numDer number;    //number could be any user defined type derived from numBase 
numDer& containerBase::count = number; //initialize count to a kind of numBase 

int main() 
{ 
    containerDerived container1; 
    containerDerived container2; 

    container1.printCount(); 
    container1.inc(); 
    container2.inc(); 
    container1.printCount(); 
} 

Спасибо.

+0

'numBase' - пустой класс. Он не имеет метода 'inc()'. Ошибка компилятора здесь довольно описательна, можете ли вы подробнее рассказать о своей реальной проблеме? –

+0

Если вы хотите полиморфизм, используйте указатели, как и везде. – molbdnilo

+0

Вы не можете, потому что 'count' является экземпляром' numBase', а не указателем 'numBase'. –

ответ

1
static numBase count; 

Вы объявили count как объект numBase. И через этот объект вы пытаетесь вызвать член производного класса numBase i.e numDer.inc(). Этот вызов, конечно, не будет выполнен, так как полиморфизм времени выполнения подходит только тогда, когда используются указатели/ссылки.

0

Вы не можете делать то, что вы пытаетесь сделать так, как вы пытаетесь это сделать.

Присвоение numDernumBase будет «разрезать» объект и не будет соответствовать типу.

Для того, чтобы получить полиморфное поведение, вы должны использовать либо указатели, либо ссылки.

Компилятор сообщает об ошибке, указывающей на то, что метод inc не существует на numBase.

Полиморфные методы должны быть объявлены в базовом классе, а также объявлены virtual.

+0

«must» - это немного сильное слово - они должны быть объявлены виртуальными. И так должен деструктор базы. В случае, когда вы никогда не планируете объявлять базовый случай как указатель/ссылку на производный класс, виртуальная декларация вообще не нужна. Опускание ключевого слова virtual может также ускорить вашу программу, учитывая оптимизатор. –

+0

Фактически вы не получите полиморфное поведение метода, если оно не объявлено виртуальным. Вместо этого вы получаете метод shadowed, и если вызывается указатель на базу, вы всегда получаете базовую реализацию. Итак, ** если ** желаемое поведение - это полиморфизм, то «must» подходит. Поскольку вопрос является как помеченным, так и полиморфизмом состояний, он, безусловно, звучит как «обязательный». Кроме того, ваше утверждение о запуске быстрее бесполезно, если вызывается неправильный метод и происходит неправильное поведение. – b4hand

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