Если у вас есть какие-либо класс, который имеет защищенную или частную Конструктора, считается, что класс «абстрактный объект класса» Это означает, что она представляет собой концепцию или идею о том, что объект должен быть как и все элементы комментария. Вы не можете создать экземпляр объекта этого типа напрямую! Таким образом, вы должны унаследовать от этого класса, кто конструкторы являются публичными, если они не являются абстрактными. Другая идея состоит в том, чтобы быть специализированным объектом, который не может быть непосредственно создан, но может быть дружественным к другим классам, где их методы могут создавать экземпляр объекта, то есть те классы, у которых есть доступ к другу этого абстрактного класса, смогут создать экземпляр этого объекта, который будет жить в течение жизни и объема объекта класса друзей.Примеры:
class A {
public:
enum ClassType {
TYPE_A = 0,
TYPE_B,
TYPE_C,
TYPE_D,
TYPE_E,
TYPE_F
};
private:
unsigned m_uId;
protected:
explicit A(A::ClassType type) :
m_uId(static_cast<unsigned>(type) {}
void initialize() = 0; // Purely Abstract - Each Derived Class Must Create This Function
void cleanup();
};
class B sealed : public A {
public:
B() : A(TYPE_A) {}
void initialize() override;
};
class C sealed : public A {
public:
C() : A(TYPE_C) {}
void initialize() override;
};
class D : public A {
protected:
D(A::ClassType type) : A(type) {}
void initialize() override = 0;
};
class E sealed : public D {
public:
E() : D(TYPE_E) {}
void initialize() override;
};
class F sealed : public D {
public:
F : D(TYPE_F) {}
void initialize() override;
};
Здесь я демонстрирую полиморфное наследование. Класс A & D вы не можете создавать объекты для объектов, однако классы B, C, E & F вы можете создавать объекты. Поскольку конструкторы для A & D защищены, любой производный класс имеет к ним доступ. С помощью этой установки каждый класс имеет доступ к A :: cleanup(), и каждый класс должен реализовать свою функцию: initialize() override.
Для этой следующей части я продемонстрирую использование абстрактного класса, который могут использовать классы друзей.
class Counter {
friend unsigned Object1::getCount();
friend unsigned Object2::getCount();
private:
static unsigned m_uCounter;
Counter() { ++m_uCounter; }
public:
unsigned getCounter() { return m_uCounter; }
};
class Object1 {
friend class Counter;
private:
unsigned m_uCount;
public:
Object1() : m_uCount(0) {}
void count() {
Counter counter;
m_uCount = counter.getCounter();
}
unsigned getCount() const { return m_uCounter; }
};
class Object2 {
friend class Counter;
private:
unsigned m_uCount;
public:
Object2() : m_uCount(0) {}
void count() {
Counter counter;
m_uCount = counter.getCounter();
}
unsigned getCount() const { return m_uCount; }
};
Этого код показывает, как использовать абстрактный класс, который не может быть объявлен сама по себе, но может быть использована в других классах, будучи другим классом. В этой ситуации только демонстрацией единственной целью класса Counter является выполнение работы по увеличению. Класс счетчика не может быть автономным объектом, который не имеет смысла иметь, однако его использование в других классах через объявления друзей позволяет этим классам иметь доступ к его конструктору через объявление функции из внешних классов, объявленных как функции друга в абстрактном классе. Такая настройка позволяет только Object1 :: getCount() и Object2 :: getCount() объявлять тип счетчика и иметь доступ к Counter :: getCounter().
Надеюсь, это поможет вам понять в абстрактных классах, которые касаются полиморфизма с использованием наследования, ассоциации абстрактного класса через использование друга и как правильно объявить абстрактный тип.
В вашем коде, в котором другие адресовали A A(); объявляет прототип функции, где A a1; пытается объявить тип A, который является абстрактным!
'A a();' объявляет функцию. Конечно, все в порядке. – Columbo