Здравствуйте, rg45, Вы писали:
R>Тебя удивляет, что компилятор не возражает против определения чисто виртуальной функции?
Возражает
class A{
virtual void f() = 0;
};
void A::f()
{
}
int main()
{
A a;
return 0;
}
1>e:\45555252\1.cpp(11) : error C2259: 'A' : cannot instantiate abstract class 1> due to following members: 1> 'void A::f(void)' : is abstract 1> e:\45555252\1.cpp(2) : see declaration of 'A::f'
>Ты еще больше удивишься когда узнаешь, что это полностью соответствет стандарту, см. 10.4/2.
.А еще можешь переделать свой пример для "традиционнго" объявления, ты убедишься, что в этом случае можно определить чисто виртуальную функцию. Только, на всякий случай, определение чисто виртуальной функции болжно быть выполнено за пределами определения класса согласно все тому же пункту стандарта.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, rg45, Вы писали:
R>>Тебя удивляет, что компилятор не возражает против определения чисто виртуальной функции?
PD>Возражает
1>>e:\45555252\1.cpp(11) : error C2259: 'A' : cannot instantiate abstract class 1>> due to following members: 1>> 'void A::f(void)' : is abstract 1>> e:\45555252\1.cpp(2) : see declaration of 'A::f'
>>Ты еще больше удивишься когда узнаешь, что это полностью соответствет стандарту, см. 10.4/2.
PD>Значит, VC 2008 не соответствует стандарту
>>... можно определить чисто виртуальную функцию. Только, на всякий случай, определение чисто виртуальной функции болжно быть выполнено за пределами определения класса согласно все тому же пункту стандарта.
PD>Как видишь, в VC2008 нельзя.
Ну у нас получается разговор слепого с глухим, честное слово. Обрати внимание на выделенные фразы. Я говорю: "можно определять чисто виртуальные функции", а ты мне возражаешь: "нет, объекты абстрактных классов создавать нельзя" . На самом деле оба эти утверждения верны и друг другу не противоречат. Объекты абстрактных классов действительно нельзя создавать, но при этом можно давать определения чисто виртуальных функций классов этих объектов.
А все недоразумение началось из-за неполноты приведенного тобой примера: здесь
. По этому фрагменту и комментариям в нем можно сделать только один вывод, что ты не знаешь о том, что у чисто виртуальных функций могут быть определения. Но, как я теперь уже понимаю благодаря постам других участников, ты хотел именно сказать о глюках майкрософтовских компиляторов, которые пропускают создание объектов абстрактных классов. Это действительно ценные сведения, спасибо.
--
Справедливость выше закона. А человечность выше справедливости.
R>Как вы считаете, имеет ли какой-нибудь смысл, например, такое объявление: R>
R>typedef int Foo(const char*) const;
R>
R>и в какой области такое объявление может располагаться? Оказывается, имеет и может располагаться вне определения класса, не смотря на модификатор const.
Кстати, в Active Issue 547 предлагается ослабить ограничение на допустимые места, в которых можно использовать квалификатор const и разрешить такое:
template<class T> struct X;
// partial specialization for a const member function:template<class R> struct X< R() const >
{};
R>А вот пункт стандарта, который все это благословляет: 9.3/9.
Не совсем: 8.3.5/4 разрешает использование cv-qualifier в typedef declaration для top-level function type, а 8.3.5/7 разрешает использовать объявленные таким образом имена при объявлении функций-членов. С volatile такой фокус также проходит.
// Называется "попробуй не специально сделать различные параметры по-умолчанию у предка
// и наследника в виртуальных функциях при соблюдении такого синтаксиса":typedef void SomeMethod ( int = 42 ) const;
struct A {
virtual SomeMethod m = 0;
};
struct B : A {
virtual SomeMethod m;
};
void B::m ( int ) const {
}
ИМХО, такие typedef-ы (я не про параметры по-умолчанию, а вообще) — очень крутая фича
Здравствуйте, Alexey F, Вы писали:
AF>Здравствуйте, rg45, Вы писали:
AF>...И, конечно же , такое: AF>
AF>// Называется "попробуй не специально сделать различные параметры по-умолчанию у предка
AF>// и наследника в виртуальных функциях при соблюдении такого синтаксиса":
AF>typedef void SomeMethod ( int = 42 ) const;
AF>struct A {
AF> virtual SomeMethod m = 0;
AF>};
AF>struct B : A {
AF> virtual SomeMethod m;
AF>};
AF>void B::m ( int ) const {
AF>}
AF>
AF>ИМХО, такие typedef-ы (я не про параметры по-умолчанию, а вообще) — очень крутая фича
Параметры по умолчанию (как и exception specification) не могут быть использованы в таком контексте (8.3.6/3, 15.4/1).
. По этому фрагменту и комментариям в нем можно сделать только один вывод, что ты не знаешь о том, что у чисто виртуальных функций могут быть определения.
Определения быть могут, и это я знаю, но от того, что у чисто виртуальной функции появится определение, класс, содержащий такую функцию, не перестанет быть абстрактным , и инстансы его создавать нельзя. VC 2008 вполне следует этому правилу для явно описанных чисто виртуальных функций и не следует для описанных через этот самый typedef.
>Но, как я теперь уже понимаю благодаря постам других участников, ты хотел именно сказать о глюках майкрософтовских компиляторов, которые пропускают создание объектов абстрактных классов.
Дело не в том, что он пропускает. Он не считает этот класс абстрактным!!!
class A {
virtual void f() = 0;
};
void A::f()
{
}
int _tmain(int argc, _TCHAR* argv[])
{
A a;
return 0;
}
Описание чисто вирт. функции есть, но тем не менее класс абстрактный
1>e:\4111111\4111111.cpp(16) : error C2259: 'A' : cannot instantiate abstract class 1> due to following members: 1> 'void A::f(void)' : is abstract 1> e:\4111111\4111111.cpp(7) : see declaration of 'A::f'
А теперь
typedef void F(void);
class A {
virtual F f = 0;
};
void A::f()
{
}
int _tmain(int argc, _TCHAR* argv[])
{
A a;
return 0;
}
и программа замечательно начинает выполняться и экземпляр A a нормально создается!
Здравствуйте, Pavel Dvorkin, Вы писали:
>>Но, как я теперь уже понимаю благодаря постам других участников, ты хотел именно сказать о глюках майкрософтовских компиляторов, которые пропускают создание объектов абстрактных классов.
PD>Дело не в том, что он пропускает. Он не считает этот класс абстрактным!!!
Не пойму я что-то. Каковы отличительные признаки "допускает создание объектов абстрактного класса" от "не считает класс абстрактным"?
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
R>Не пойму я что-то. Каковы отличительные признаки "допускает создание объектов абстрактного класса" от "не считает класс абстрактным"?
А что же тут непонятного ? Если компилятор считает, что класс абстрактный, но при этом допускает создание экземпляров — это одно, это явная ошибка компилятора. Если же компилятор не считает класс абстрактным, тогда создавать экземпляры он имеет полное право, а вопрос же — верно ли он так считает ?