*당신*은 C++ ABC 생성자를 무엇에 사용합니까?
-
19-08-2019 - |
문제
여기 사람들은 현장에서 C++ 추상 기본 클래스 생성자를 무엇에 사용합니까?나는 데이터 멤버가 없고 순수하지 않은 가상 멤버가 없는 순수 인터페이스 클래스에 대해 이야기하고 있습니다.
ABC 생성자를 유용한 방식으로 사용하는 관용어를 보여줄 수 있는 사람이 있나요?아니면 ABC를 사용하여 비어 있고 인라인이며 보호되는 인터페이스를 구현하는 것이 본질적인 것일까요?
해결책
누구든지 ABC 생성자를 사용하는 관용구를 유용한 방식으로 시연 할 수 있습니까?
예를 들어, 예를 들어, 그것은 불명예스러운 예입니다.
모든 인스턴스의 목록을 유지하는 데 사용할 수 있습니다.
class IFoo
{
private:
//static members to keep a list of all constructed instances
typedef std::set<IFoo*> Set;
static Set s_set;
protected:
//new instance being created
IFoo()
{
s_set.insert(this);
}
public:
//instance being destroyed
virtual ~IFoo()
{
s_set.remove(this);
}
... plus some other static method and/or property
which accesses the set of all instances ...
};
아니면 ABC를 사용하여 비어 있고 인라인 및 보호 된 인터페이스를 구현하는 것이 본질적으로 본질적입니까?
더 일반적으로 그들은 전혀 선언되지 않습니다! 그들을 선언 할 이유가 없습니다.
- 비어 있고 인라인 => 왜 그것을 선언 하는가?
- Protected => ABC는 이미 일부를 가지고있을 것입니다 순수한 가상 따라서 방법은 서브 클래스를 제외하고 이미 인스턴스화 할 수 없습니다.
다른 팁
모든 파생 클래스에 공통적 인 행동이 있다고 가정 해 봅시다. 일부 외부 레지스트리에 등록하거나 무언가의 유효성을 확인하는 것과 같은.
이 모든 공통 코드는 기본 클래스의 생성자에 배치 될 수 있으며, 각 파생 클래스의 생성자에서 암시 적으로 호출됩니다.
어떻게 ~할 수 있었다 추상 기본 클래스의 생성자를 어떤 용도로든 사용할 수 있나요?
추상 기본 클래스 B와 파생 클래스 D가 있다고 가정합니다.D 유형의 객체가 생성되면 B의 생성자가 먼저 호출되지만 그 시점에서 객체는 여전히 B 유형입니다(참조: 여기) - 특히 B의 생성자 본문에서 가상 함수를 호출하면 다음이 호출됩니다. B의 자체 구현 그 기능 중.그러나 B가 순수 추상 클래스인 경우 해당 가상 함수 중 어느 것도 정의되지 않으므로 프로그램이 즉시 중단됩니다.
나는 B의 생성자가 가장 많이 파생된 클래스(예:D's) 가상 함수 구현이죠?D의 객체가 아직 완전히 구성되지 않았기 때문에 이는 일반적으로 나쁜 생각입니다. 따라서 D의 가상 함수 구현 내부에서 D의 멤버 변수에 액세스하면 초기화되지 않은 메모리에 액세스하게 됩니다.
기억하다: "자원 획득은 초기화입니다".
때때로 우리는 추상 기본 클래스를 일종의 잠금 메커니즘으로 사용합니다. 예를 들어, 여러 스레드가 단일 리소스를 공유 해야하는 다중 스레드 환경에서 스레드는 자원을 획득하는 방법으로 생성자를 사용할 수 있으며 자원을 해제 할 수 있습니다.
void PlayWithPaintBallGun(Target &target)
{
PaintBallGun paintBallGun; // constructor waits until the gun is free,
// then picks it up.
paintBallGun.Aim(target); // Shoot something
paintBallGun.Fire(); //
// Clever! The destructor is automatically
// called when it goes out of scope. So we
// can't forget to put the gun down.
}
휴고
나는 많은 유용한 예를 생각할 수 없다. 데이터 멤버가없는 클래스는 상태가 없으므로 아무것도 초기화 할 수 없습니다. 그래도 생성자/소멸자가 로깅을 할 수 있습니다. 예를 들어, 모든 방문객 개체의 생성/파괴를 기록하려면 :
class Visitor {
public:
Visitor() {
std::cout << "Visitor@" << this << " created"
<< std::endl;
}
virtual ~Visitor() {
std::cout << "Visitor@" << this << " destroyed"
<< std::endl;
}
virtual void visitA(A*) = 0;
virtual void visitB(B*) = 0;
// ...
};
일반적으로 멤버를 합리적인 가치로 초기화하는 것만으로도 전적으로.