말 그대로
순수 추상 클래스_1
|
순수 추상 클래스_2 : public 순수 추상 클래스_1
|
오브젝트
이런식인데
코드적으로 보여드리면
class IUnit
{
public:
virtual voic Action() abstract;
}
template<class T>
class Unit : publuc IUnit
{
public:
virtual voic Action() abstract;
protected:
T* Controllor= nullptr;
}
class Object : public Unit<ObjectController>
{
public:
Object(ObjectController* _Controller)
: Unit<ObjectController>(_Controller) { }
virtual voic Action() override
{
// 구현
}
}
이런 식은데 디자인적으로 문제없을까요?
Unit::Action을 그냥 비어있는 상태로 구현하는게 좋을지 아니면 계속 순수가상함수로 또 다시 선언해야 하는지 고민입니다.
빈 함수로 만들면 가상함수 테이블 쪽이 낭비일거 같은데
두 번 이상 순수가상함수로 만들어도 문법상 허용되니깐 문제없지만 실제 사용해도 딱히 문제없을지 고민입니다.
이렇게 된 이유가... Command 클래스가 템플릿으로 해야 되다보니 발생한 문제인데요
요약하면
1. 순수 가상함수를 연속 2번 만들어도 되는지
2. 자식 Command에서 가상함수로 구현했다면 가상함수 테이블이 낭비가 있는지
알고 싶습니다.
===========
2번 내용은 이렇게 만들 경우 발생하는 낭비? 그런 질문입니다.
template<class T>
class Unit : publuc IUnit
{
public:
virtual voic Action() override
{
// empty
}
protected:
T* Controllor= nullptr;
}
아퇴근하고싶다
https://stackoverflow.com/questions/50839210/abstract-class-inheriting-another-abstract-class-in-c
이게 좀 비슷한가?
검색 키워드
Pure Abstract Class Inherits Pure Abstract Class
RX7900XTX
ㅇㅇ 완전 동일한듯? 흠 아래 설명처럼 object를 template으로 만드는 방법 생각해봐야 할 듯
야옹아멍멍해봐
요즘 oop추세가 계층화는 최소한으로 하는거라 꼭 필요해서가 아니라면 저렇게 안하는 걸 추천.
그리고 구조를 보면 unit을 template로 하지 않고 object를 template으로 만들거나 그냥 controller별로 모두 따로 구현하는게 나아보여
RX7900XTX
아 다시 코드 보고 있는데 설명 덜 한거 같음
object를 가지는 class가 있는데
흠... 예를들면
class Group
{
public Add_Object(IUnit* _NewUnit) { // 구현 생략 }
private:
list<IUnit*> ObjectList;
}
이거 때문에 IUnit을 만든걸 설명 안 함;;;;
Group MainGroup;
MainGroup.Add_Object(new Unit<Ctrl_Monster>());
MainGroup.Add_Object(new Unit<Ctrl_Character>());
MainGroup.Add_Object(new Unit<Ctrl_SubWeapon>());
이런식으로 할려고 만든건데요
이게 Group에서 Action함수를 호출해야 하는데 템플릿을 써서
Unit을 멤버로 못가지니깐 IUnit라는 부모를 만든거임
RX7900XTX
사실 커맨드 패턴 연습하다 그런거라서 아래 코드가 더 명확하겠네요;;;;
class ICommand
{
public:
virtual void Excute() abstract;
};
template<typename T>
class Command
: public ICommand
{
public:
Command(T* _Subject)
: m_Subject(_Subject)
{ }
public:
virtual void Excute() abstract;
protected:
T* m_Subject;
};
// =================
class Heater // 생략
class Light // 생략
// =================
class HeaterOnCommand
: public Command<Heater>
class LightOnCommand
: public Command<Light>
class LightOnCommand
: public Command<Light>
class LightOnCommand
: public Command<Light>
// =================
class AISpeaker
{
public:
void Set_CurCommand(ICommand* _NewCommand)
{
if (m_CurCommand)
delete m_CurCommand;
m_CurCommand = _NewCommand;
}
void Activate_CurCommand()
{
if (m_CurCommand)
m_CurCommand->Excute();
}
private:
ICommand* m_CurCommand = nullptr;
}
이 구조 때문에 그럼....
솔찍히 Command 자식 클레스에 멤버로 Light나 Heater 멤버로 선언하기 귀찮아서 그랬음....
실제에서는 Light, Heater가 동일 부모로 상속받는 구조라서 Excute의 매개변수로 전달하면 될텐데
HeaterOnCommand 같은 Excute 함수 안에서 형 변환해야 하니깐 어떻게 편하게 하는 방법없을까?
해서 템플릿화 시킴
1. Command의 자식 m_Subject의 템플릿화 때문에
2. Command를 상속받는 자식 클래스의 Excute 함수 내에서 m_Subject 접근이 용의하게 하기 위함(형변환없이)
야옹아멍멍해봐
저런 계층 세분화의 당위성이 분명하다면 문제는 없다고 봐.
근데 중간에 낀 command 클래스 또한 추상클래스라면 execute 추상 메소드 선언은 다시 할 필요 없지 않아? 없으면 컴파일에러 생겨?
RX7900XTX
문법상은 문제가 없는데 디자인적이나 효율성에 문제가 없을까 궁금해서 물어본거
컴파일 단계에서 차이가 있을까 의문이 든거
2중 순수가상함수로 했을 때 컴파일 단계에서도 동일한지 궁금했던거
개인적인 생각에는 2중 순수가상함수가 가상함수 테이블이 더 간결하지 않을까?하는 의문이들어서 그럼
command 가 만약 단순 가상함수라면 가상함수 테이블에 command ::excute가 저장되는데
2중 순수가상함수면 가상함수테이블 command::excute이 없지 않을까?하는 의문이 생김
이거 전문가들 어셈블리어인가? 뭔가로 보던데 볼 줄몰라서요...
VXcePsbmqh
정말 굳이 상속을 하고싶으면 딱 3단계까지 하는걸 추천함
자바기준으로 인터페이스-앱스트랙트클래스-클래스 이런느낌
근데 본인이 자바 코딩스타일 얘기할땐 앱스트랙트 클래스도 되도록 만들지 말라고 함
심지어 인터페이스조차도 되도록 쓰지 말고 POJO만 쓰게끔 유도함
상속 자체가 굉장한 스트레스를 줌
RX7900XTX
흠... 오늘 이터페이스랑 추상클래스 좀 더 파야겠네요 ;;;
사용법만 알지 이론 개념은 약해서;;;;
VXcePsbmqh
특히나 C++는 상속 쉽게쉽게 생각하다가 흑마술을 의도치않게 써버리는 경우가 흔해서 정말조심해야함
RX7900XTX
흑마술이라는데 어떤 은어죠....?
VXcePsbmqh
diamond 상속이 대표적인 사례인디...
사실 이런 피로가 너무 심해지니까 자바쪽에선 굳이 POJO(Plain Old Java Object)라는 말을 만들어서 보급시킴
별 말이 아니고, "상속도 뭣도 없는 그냥 클래스" 라는 뜻임
RX7900XTX
아 다중상속 문제ㅋㅋㅋ
거의 쓰지말라고 해서 안 써야지 했는데 언리얼 엔진단에서 자주 쓰는거 보고 당황함 ㅋㅋㅋ
VXcePsbmqh
그런것들이 효율을 위한 흑마술의 일종... 근데 정말 필요할때만 써야한다는것...안쓸순없고 ㅠㅠ
반박시내말이맞음
복잡해잉