2015-08-30 3 views
2

Допустим, у меня есть базовый класс A и производные классы B и C. Я хочу иметь возможность выполнить метод производной функции с помощью указателя ссылки типа A. Я попытался использовать виртуальные функции:ссылка на виртуальную функцию

class A 
{ 
public: 
    virtual std::string a() { return "a() of a"; } 
    virtual std::string b(); 
    virtual std::string c(); 
}; 

class B : public A 
{ 
public: 
    std::string a() { return "a() of b"; } 
    std::string b() { return "b() of b"; } 
}; 

class C : public A 
{ 
public: 
    std::string a() { return "a() of c"; } 
    std::string c() { return "c() of c"; } 
}; 

int main(int argc, char** argv) 
{ 
    B b; 
    C c; 

    A* a1 = &b; 
    A* a2 = &c; 

    std::cout << a1->b() << std::endl; 
    std::cout << a2->c() << std::endl; 

    return 0; 
} 

Но я продолжаю получать это:

/tmp/ccsCMwc6.o:(.rodata._ZTV1C[_ZTV1C]+0x18): неопределенная ссылка на A::b()' /tmp/ccsCMwc6.o:(.rodata._ZTV1B[_ZTV1B]+0x20): undefined reference to A :: гр() '/tmp/ccsCMwc6.o:(.rodata._ZTI1C[_ZTI1C]+0x10): undefined ссылка на typeinfo for A' /tmp/ccsCMwc6.o:(.rodata._ZTI1B[_ZTI1B]+0x10): undefined reference to typeinfo for A '

Помощь?

+0

Не забудьте виртуальный деструктор. –

ответ

1

Компилятор создаст таблицу виртуальных функций (vtbl) для каждого класса, которая указывает на реализацию всех виртуальных функций этого класса, для класса A она ожидает найти реализации A :: b() и A :: c().

Если вы не хотите, чтобы их реализовать, вам нужно объявить их как чисто виртуальный:

class A 
{ 
public: 
    virtual std::string a() { return "a() of a"; } 
    virtual std::string b() = 0; 
    virtual std::string c() = 0; 
}; 
1

Все виртуальные функции должны иметь определение (реализацию).

+0

Но что, если A не использует эти функции? Есть ли какое-либо ключевое слово, которое может помешать написанию ограничений? И что, если возвращаемый тип b() и c() является строкой - есть ли возвращаемое значение строки по умолчанию? –

+0

@AlexGoft Создание их * абстрактных * возможно? Но тогда функция должна определяться производными классами. –

0

У меня все хорошо. Вам не нужно иметь определения в базовом классе, если вы только создаете экземпляр унаследованного класса.

Какой он компилятор?

+0

g ++ -std = C++ 11 -Wextra -Wall –

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