Вот класс с неопределенным методом. Кажется, компиляторы позволяют экземпляры этого класса должны быть построены до тех пор, пока функция не определена член никогда не называют:Разрешены ли все неиспользуемые неопределенные методы?
struct A {
void foo();
};
int main() {
A a; // <-- Works in both VC2013 and g++
a.foo(); // <-- Error in both VC2013 and g++
}
Вот такая же ситуация, но один, который включает в себя наследование. Подкласс Bar
расширяет базовый класс Foo
. Foo
определяет способ g()
. Bar
объявляет одноименном метод, но не определяет его:
#include <iostream>
struct Foo {
void g() { std::cout << "g\n"; }
};
struct Bar : Foo {
void g();
};
int main() {
Bar b; // Works in both VC2013 and g++
b.Foo::g(); // Works in both VC2013 and g++
b.g(); // Error in both VC2013 and g++
}
Вот вариант выше. Единственное отличие в том, что g()
является virtual
как к Foo
и Bar
:
#include <iostream>
struct Foo {
virtual void g() { std::cout << "g\n"; }
};
struct Bar : Foo {
virtual void g();
};
int main() {
Bar b; // Works in g++. But not in VC2013, which gives
// 'fatal error LNK1120: 1 unresolved externals'
b.Foo::g(); // Works in g++, but VC2013 already failed on b's construction
b.g(); // Error in g++, but VC2013 already failed on b's construction
}
Смотрите комментарии кода для контраста различного поведения между VC2013 и г ++.
- Какой компилятор прав, если таковые имеются?
- Почему у компилятора VC2013 есть несколько разных жалоб в своей версии с ключевым словом
virtual
по сравнению с тем, что в его версии, без ключевого словаvirtual
? - Неиспользованные неиспользуемые методы всегда разрешены? Если нет, то каковы все случаи, когда они не разрешены?
- Заявление
Bar
g()
считается переопределяющим , даже еслиBar
не содержит определения?
vtable ссылается на конструктор, и ему нужны адреса виртуальных функций, поэтому ошибка VC2013 представляется разумной. – BartoszKP