Здравствуйте, Bell, Вы писали:
B>Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>>Дак даже VC 6.0 скажет
L_L>>
L_L>>D:\test\main.cpp(13) : error C2838: illegal qualified name in member declaration
B>А вот VC7.1 даже не поперхнулся
Н-да. Приношу извинения за туфту.
Я в VC и смотрел и благодаря ему, любимому, уже давно считал что это абсолютно валидный код.
Попутно хотелось бы спросить, такой код:
class C
{
typedef int pfn(int, int);
pfn z;
};
int C::z(int, int)
{
return 0;
}
Здравствуйте, Bell, Вы писали:
_W>>Господа, не выключайте варнинги своего компилятора! B>Мне кажется, тут нужно немного перефразировать: "Господа, включайте все варнинги своего компилятора, которые отключены по умолчанию!" Ибо в VC7.1 C4263 и C4264 off by default B>
Варнингы включены всегда и все. Только если функцию переименовать, никаких варнингов все равно не будет. В варианте remark и в моем, конечно будет ошибка компиляции. Т.е., гораздо ближе к тому что действительно называется override.
On Thu, 08 Dec 2005 14:36:17 +0200, wrote:
> Наступил давеча на такие грабли. В базовом классе объявлена вирт. ф-ция, которая понятно переопределяется в наследуемых классах. Схема наследования такая: > > >
>
> class Base { virtual foo() = 0; }
> class Derived : public Base { virtual foo() {}; }
> class Derived1, Derived2, ..., DerivedN : public Derived ;
>
>
> > Основная масса классов пользуется ф-цией, определенной в Derived, но в некоторых из DerivedX требуется переопределять ф-цию foo() специфичным образом. В один прекрасный момент понадобилось изменить прототип ф-ции foo() в классе Base, что и было успешно сделано. Прототип в Derived тоже был изменен ( забыть об этом было нельзя, т.к. foo() в Base чисто виртуальная), а вот про некоторые из классов DerivedX благополучно было забыто (т.к.их достаточно много). Вопрос в том, как писать безопасный код, гарантированно исключающий такие ситуации?
ето плохо, когда спроектированый интерфейс приходитса менять.
мне намисль приходит только одно решение:
class Base { public: virtual foo() = 0; }
class Derived : public Base { protected: __foo() {}; }
class Derived1, Derived2, ..., DerivedN : public Derived
{
public: virtual foo(){Derived::__foo()}
}
тогда у тебя выдет што виртуальная ф-ция переопределена в каждом класе, и компилер плюнетса всюду, но придетса немножко пописать
другой вариант — ето поиск по имени ф-ции по всем заголовочным файлам
Posted via RSDN NNTP Server 1.9
make it simple as possible, but not simpler
Re[10]: Изменение прототипа вирт ф-ции в базовом классе
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, Chez, Вы писали:
C>>Это тоже только для VC нормально? Или стандарт? B>Да, тут все в порядке — смотри 9.3/9. B>
Хи, там написано:
[Note: a member function can be declared (but not defined) using a typedef for a function type. The resulting
member function has exactly the same type as it would have if the function declarator were provided
explicitly, see 8.3.5. For example,
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>>>Второе C>>это радует
L_L>Опять какая-нить черная магия?
Да. Я недавно писал про то что хочу сделать Проект "Рефлексия C++"
Здравствуйте, Bell, Вы писали:
B>... Ну так в твоем примере речь шла только о декларации B>Насчет возможности определения — да.
А рвзве выделенное жирным:
class C
{
typedef int pfn(int, int);
pfn z;
};
int C::z(int, int)
{
return 0;
}
Это не определение?
Меня смущает что в примере показано определение только через присваивание.
Здравствуйте, Chez, Вы писали:
C>Здравствуйте, Bell, Вы писали:
B>>... Ну так в твоем примере речь шла только о декларации B>>Насчет возможности определения — да. C>А рвзве выделенное жирным: C>
Здравствуйте, Lorenzo_LAMAS, Вы писали:
B>>Определение, только в стандарте имеется ввиду определение в теле класса.
L_L>В стандарте имеется в виду, что тайпдеф, задающий тип функции, не может использоваться в определении, а может только в объявлении.
+1
Проиллюстрирую:
class C
{
typedef int pfn(int, int);
pfn z;
};
//well-formedint C::z(int, int)
{
return 0;
}
//ill-formed
C::pfn C::z
{
return 0;
}
... << RSDN@Home 1.1.4 stable rev. 510>>
Re: Изменение прототипа вирт ф-ции в базовом классе
Здравствуйте, Аноним, Вы писали:
А> Вопрос в том, как писать безопасный код, гарантированно исключающий такие ситуации?
Мне кажется это именно та проблема, которая решается использованием т.н Nonvirtual Interface pattern (NVI) при проектирвании классов, почитать об этом можно у Саттера: у него на сайте, в CUJ, в поздних книжках (С++ Coding Standards: 101... chapter 39; Exceptional C++ Style chapter 18 etc.)
Re: Изменение прототипа вирт ф-ции в базовом классе
class Base
{
public:
typedef int foo_t(int, double);
virtual foo_t foo;
};
class Derived : public Base
{
public:
virtual foo_t foo;
};
int Derived::foo(int x, double z)
{
return 0;
}