class A
{
virtual public A MethodFoo() {...}
}
Создать экземпляр текущего класса
Например:
Код:
Пусть MethodFoo возвращает объект класса A. Необходимо, чтобы его наследник class B : A при вызове B.MethodFoo() возвращал не A, а B. Без перекрытия метода в B. Т. е. на лету взять текущий класс и создать объект этого типа.
Код:
class A
{
public:
virtual A *CreateInstance(void) { return new A; };
};
class B : public A
{
public:
virtual A *CreateInstance(void) { return new B; };
};
{
public:
virtual A *CreateInstance(void) { return new A; };
};
class B : public A
{
public:
virtual A *CreateInstance(void) { return new B; };
};
Вопрос не понят. Нужно как раз избавиться от перекрытия MethodFoo() в наследниках
Действительно, не понят. То есть в наследнике должны быть методы создания и A, и B?
Например, мы всегда можем получить актуальный тип объекта GetType(), а как создать экземпляр именно этого класса?
Что-то вроде такого (естественно, не работает):
Код:
virtual public A MethodFoo()
{
Type t=this.GetType();
return new t();
}
{
Type t=this.GetType();
return new t();
}
Именно это и сделано в примере. Я не понял, что значит "Нужно как раз избавиться от перекрытия MethodFoo() в наследниках".
Я правильно понял?
MemberwiseClone (защищённый метод Object). Я, правда, не пробовал так делать и не гарантирую, что получится. :)
Не совсем понятно, зачем такое может потребоваться, чтобы ещё и переопределять нельзя было свой метод, но можно попробовать в своём методе использовать клонирование объекта с помощью
Можно создать метод само-клонирования типа (см. пример _const_).
Можно различными способами получать информацию о типе.
Вариант первый:
Код:
template<class T>
class A
{
public:
T* CreateInstance(void) {
return new T;
}
};
// использование
class B : public A<B>
{
};
class A
{
public:
T* CreateInstance(void) {
return new T;
}
};
// использование
class B : public A<B>
{
};
Вариант второй:
Код:
class A
{
public:
template<class T>
T* clone(T*) {
return new T;
}
};
// использование
class B : public A
{
void func() {
B* b = clone(this);
}
};
// использование
B b;
B* pB = b.clone(&b);
{
public:
template<class T>
T* clone(T*) {
return new T;
}
};
// использование
class B : public A
{
void func() {
B* b = clone(this);
}
};
// использование
B b;
B* pB = b.clone(&b);
В этом случае необязательно, чтобы clone был методом класса, это может быть и просто функция:
Код:
template<class T>
T* clone(T*) {
return new T;
}
// использование
B b;
B* pB = clone(&b);
string str;
string* pStr = clone(&str);
T* clone(T*) {
return new T;
}
// использование
B b;
B* pB = clone(&b);
string str;
string* pStr = clone(&str);
Код:
class A : public CObject
{
DECLARE_DYNCREATE(A)
public:
A() {}
virtual ~A() {}
virtual PrintSelf() { printf("I am of class A\n"); }
A* CreateInstance()
{
CRuntimeClass *c = this->GetRuntimeClass();
return (A*)c->CreateObject();
}
};
class B : public A
{
DECLARE_DYNCREATE(B)
public:
B() {}
virtual ~B() {}
virtual PrintSelf() { printf("I am of class B\n"); }
};
IMPLEMENT_DYNCREATE(A, CObject)
IMPLEMENT_DYNCREATE(B, A)
{
DECLARE_DYNCREATE(A)
public:
A() {}
virtual ~A() {}
virtual PrintSelf() { printf("I am of class A\n"); }
A* CreateInstance()
{
CRuntimeClass *c = this->GetRuntimeClass();
return (A*)c->CreateObject();
}
};
class B : public A
{
DECLARE_DYNCREATE(B)
public:
B() {}
virtual ~B() {}
virtual PrintSelf() { printf("I am of class B\n"); }
};
IMPLEMENT_DYNCREATE(A, CObject)
IMPLEMENT_DYNCREATE(B, A)
Код:
B* b = new B();
b->PrintSelf();
A* a = b->CreateInstance();
a->PrintSelf();
b->PrintSelf();
A* a = b->CreateInstance();
a->PrintSelf();
чтобы всё это работало необходимо включить RTTI в свойствах проекта.
сорри за не совсем красивый код -- специально заихнул классы полностью в один файл