C++의 다형성에 문제가 있습니다. 내가 클래스를 초기화하기위한 다소 이상한 구문을 만들려고하지만 그것은 내가 "이"기본 클래스 메서드에서 반환 할 때 새로 만든 된 파생 클래스를 잃어 버리고있어 나타납니다.C++의 기본 클래스에서 파생 된 "this"를 반환하는 다형성
아래의 의사 코드에서 기본 동작을 수행 할 수있는 Base :: initWithPuppies()가 있어야하며이 클래스에서 호출하는 파생 클래스를 반환 할 수 있습니다.
Bar *baz = (new Bar)->initWithPuppies();
바람직 템플릿을 사용하고 같은 캐스팅 할 필요없이 :
initWithPuppies<Bar *>();
그래, 난 오히려 괴짜 것을 알고
나는이 구문을 갖고 싶어. 그러나 그 이유가 있으며 "우수 사례"가이 상황에 적용되지 않습니다. 이것을 "만약에"이라고 생각하십시오. 아마 당신이 해야할지 :
Bar *baz = new Bar;
baz->initWithPuppies();
전 구문이 필요합니다.
의사 코드 : 편집
class Base
{
// Kittens
};
class Foo : public Base
{
public:
Base * initWithPuppies();
virtual void test() = 0;
};
Base * Foo::initWithPuppies()
{
// Call to derived works
this->test();
return this;
}
class Bar : public Foo
{
public:
void test();
};
void Bar::test()
{
std::cout << "It Works!" << std::endl;
}
// Preferred syntax
// This gives "cannot convert from 'Base *' to 'Bar *' "
Bar *baz = (new Bar)->initWithPuppies();
baz->test();
/*------------------------------------------*/
// This gives " 'test' : is not a member of 'Base' "
Base *baz = (new Bar)->initWithPuppies();
baz->test();
/*------------------------------------------*/
// This gives "Base is not a polymorphic type"
UIBar *man = dynamic_cast<UIBar *>((new UIBar)->initWithFrame());
baz->test();
:
는이 구문이 어떻게 든 가능했던 경우
Bar *baz = (Bar::create())->initWithPuppies();
더 나은 것,하지만 난 할 수 없었다 기본 클래스에서 작성하는 방법을 알아내어 타입 캐스팅없이 파생 된 새 인스턴스를 만듭니다.
Bar *baz = (Bar::create<Bar *>())->initWithPuppies();
내 대답 :는 니콜 올가미가 정확하지만
(8 시간 동안 내 자신을 대답 할 수없는) 나는 내가 사용하고자하는 구문을 언급 한 바와 같이 당신이 정말로 필요한 경우, 나쁜 관행입니다 내가 않는 한 유사한 구문을 사용하는 (요청하지 않습니다를 ...) 그런 다음이 작업을 수행 할 수 있습니다 : 당신이 유용하게 사용할 수
class Base
{
// Kittens
};
class Foo : public Base
{
public:
virtual void test() = 0;
private:
void _initWithPuppies();
};
void Foo::initWithPuppies()
{
// Do shit
}
class Bar : public Foo
{
public:
Bar * initWithPuppies();
void test();
};
Bar * Bar::initWithPuppies()
{
this->_initWithPuppies();
return this;
}
void Bar::test()
{
std::cout << "It Works!" << std::endl;
}
Bar *baz = (new Bar)->initWithPuppies();
baz->test();
호기심에서 실제로'Foo * '를 반환 할 때 함수가'Base *'를 반환하는 이유는 무엇입니까? – templatetypedef
먼저 가상 소멸자를 추가합니다.이 소멸자는 하나의 사례를 제거해야합니다. –
Foo :: initWithPuppies를 호출하고 이것을 반환하는 Bar * Bar :: initWithPuppies를 그냥 오버로드 할 수 없습니까? –