你使用C++的ABC构造函数做什么? 为什么要声明它呢? Protected=>ABC可能已经有一些纯虚拟方法,因此除了作为子类之外,已经无法实例化。
有人能用一种有用的方式演示使用ABC构造函数的习惯用法吗?或者,使用ABC实现接口的本质是保持空、内联和受保护吗?通常只将成员初始化为合理值。通常只将成员初始化为合理值。抽象基类的构造函数怎么能用于任何事情 假设您有一个抽象基类B和一个派生类D。当创建类型为D的对象时,会首先调用B的构造函数,但此时,该对象仍然是类型为B的请参见-特别是,从B的构造函数体调用任何虚拟函数都会调用B自己对这些函数的实现。但是如果B是一个纯抽象类,那么这些虚函数都没有定义,因此程序将立即崩溃你使用C++的ABC构造函数做什么? 为什么要声明它呢? Protected=>ABC可能已经有一些纯虚拟方法,因此除了作为子类之外,已经无法实例化。,c++,constructor,interface-design,abc,C++,Constructor,Interface Design,Abc,有人能用一种有用的方式演示使用ABC构造函数的习惯用法吗?或者,使用ABC实现接口的本质是保持空、内联和受保护吗?通常只将成员初始化为合理值。通常只将成员初始化为合理值。抽象基类的构造函数怎么能用于任何事情 假设您有一个抽象基类B和一个派生类D。当创建类型为D的对象时,会首先调用B的构造函数,但此时,该对象仍然是类型为B的请参见-特别是,从B的构造函数体调用任何虚拟函数都会调用B自己对这些函数的实现。但是如果B是一个纯抽象类,那么这些虚函数都没有定义,因此程序将立即崩溃 我猜你是想让B的构造函数
我猜你是想让B的构造函数调用最派生的类,比如D的虚函数实现,对吧?一般来说,这是个坏主意,因为D的对象还没有完全构造好,所以从虚拟函数的D实现内部访问D中的成员变量都会访问未初始化的内存。抽象基类的构造函数怎么能用于任何事情 假设您有一个抽象基类B和一个派生类D。当创建类型为D的对象时,会首先调用B的构造函数,但此时,该对象仍然是类型为B的请参见-特别是,从B的构造函数体调用任何虚拟函数都会调用B自己对这些函数的实现。但是如果B是一个纯抽象类,那么这些虚函数都没有定义,因此程序将立即崩溃
我猜你是想让B的构造函数调用最派生的类,比如D的虚函数实现,对吧?一般来说,这不是一个好主意,因为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.
}
Hugo记住:资源获取就是初始化
有时我们使用抽象基类作为某种锁定机制。例如,在多线程环境中,多个线程需要共享一个资源,那么一个线程可以使用构造函数作为获取资源的方式,使用析构函数释放资源
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.
}
Hugo假设所有派生类都有一些共同的行为。例如在某个外部注册表中注册自己,或者检查某个东西的有效性
所有这些通用代码都可以放在基类的构造函数中,并且将从每个派生类的构造函数中隐式调用它。假设所有派生类都有一些通用的行为。例如在某个外部注册表中注册自己,或者检查某个东西的有效性 所有这些公共代码都可以放在基类的构造函数中,并且将从每个派生类的构造函数隐式调用它 有人能用一种有用的方式演示使用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实现接口的本质是保持空的、内联的和受保护的吗
更常见的是,它们根本就没有申报!没有理由宣布:
Empty and inline=>为什么要声明它呢?
Protected=>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实现接口的本质是保持空的、内联的和受保护的吗
更常见的是,它们根本就没有申报!没有理由宣布:
Empty and inline=>为什么要声明它呢?
Protected=>ABC可能已经有一些纯虚拟方法,因此除了作为子类之外,已经无法实例化。
我不能
我想不出许多有用的例子。没有数据成员的类没有状态,因此无法初始化任何内容。不过,您可以让构造函数/析构函数为您做日志记录。例如,要记录所有访问者对象的创建/销毁,请执行以下操作:
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;
// ...
};
我想不出多少有用的例子。没有数据成员的类没有状态,因此无法初始化任何内容。不过,您可以让构造函数/析构函数为您做日志记录。例如,要记录所有访问者对象的创建/销毁,请执行以下操作:
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;
// ...
};
有时候ABC真的有一个可以初始化的变量。有时候ABC真的有一个可以初始化的变量。我猜你是想让B的构造函数调用最派生的类,比如D的虚函数实现,对吗?不,我知道你不能这么做,也许应该在我的帖子里写上。安德鲁:那么你是说那些用静态成员做事情的CTOR,比如ChrisW的例子?由于您明确表示没有数据成员和非纯虚拟成员,您的选择非常有限……我猜您打算让B的构造函数调用最派生的类,例如D的虚拟函数实现,对吗?不,我知道你不能这么做,也许应该在我的帖子里写上。安德鲁:那么你是说那些用静态成员做事情的CTOR,比如ChrisW的例子?因为您明确表示没有数据成员和非纯虚拟成员,所以您的选择非常有限……这并不能真正回答我的问题。RAII类本身不是ABC,尽管它们可以使用它们。这并不能真正回答我的问题。RAII类本身不是ABC,尽管它们可以使用它们。你的例子基本上就是我所想的。我想到的另一个想法是利用构造顺序,以便能够安全地从继承权的较低层调用一些兄弟姐妹或成员,但我真的想不出这有什么用。你的例子基本上就是我所想的。我想到的另一个想法是利用构造顺序,以便能够安全地从继承权的较低层调用一些兄弟姐妹或成员,但我真的想不出这有什么用处。