*你*使用 C++ 做什么? ABC 构造函数的用途是什么?

发布于 2024-07-11 07:10:46 字数 145 浏览 9 评论 0原文

这里的人们在现场使用 C++ 抽象基类构造函数做什么? 我说的是没有数据成员和非纯虚拟成员的纯接口类。

任何人都可以演示以有用的方式使用 ABC 构造函数的任何习语吗? 或者,这只是使用 ABC 来实现接口的本质,它们仍然是空的、内联的和受保护的?

What do people here use C++ Abstract Base Class constructors for in the field? I am talking about pure interface classes having no data members and no non-pure virtual members.

Can anyone demonstrate any idioms which use ABC constructors in a useful way? Or is it just intrinsic to the nature of using ABCs to implement interfaces that they remain empty, inline and protected?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

坏尐絯℡ 2024-07-18 07:10:46

谁能演示一下以有用的方式使用 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 实现接口的本质,它们仍然是空的、内联的和受保护的?

更常见的是,它们根本就没有被声明! 没有理由声明它们:

  • 空和内联 => 为什么要费力去声明呢?
  • 受保护=> ABC 可能已经有一些纯虚拟方法,因此除了作为子类之外无法实例化。

Can anyone demonstrate any idioms which use ABC constructors in a useful way?

Here's an example, although it's a contrived, uncommon example.

You might use it to keep a list of all instances:

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 ...
};

Or is it just intrinsic to the nature of using ABCs to implement interfaces that they remain empty, inline and protected?

More usually they're just not declared at all! There's no reason to declare them:

  • Empty and inline => why bother to declare it?
  • Protected => the ABC probably already has some pure virtual methods and therefore already can't be instantiated except as a subclass.
我的鱼塘能养鲲 2024-07-18 07:10:46

假设所有派生类都有一些共同的行为。 例如在某些外部注册表中注册自身,或检查某些内容的有效性。

所有这些公共代码都可以放置在基类的构造函数中,并且将从每个派生类的构造函数中隐式调用。

Suppose that there is some behavior that is common for all the derived classes. Such as registering itself in some external registry, or checking validity of something.

All this common code can be placed in base class's constructor, and it will be called implicitly from the constructors of each of the derived classes.

哆啦不做梦 2024-07-18 07:10:46

抽象基类的构造函数如何用于任何用途?

假设您有一个抽象基类 B 和一个派生类 D。当创建 D 类型的对象时,首先调用 B 的构造函数,但此时该对象“仍然”是 B 类型(参见 此处)——特别是从B 的构造函数将调用这些函数的B 自己的实现。 但如果B是一个纯抽象类,没有定义那些虚函数,那么程序会立即崩溃。

我猜测您打算让 B 的构造函数向下调用虚函数的最派生类(例如 D 的)实现,对吗? 一般来说,这将是一个坏主意,因为 D 的对象尚未完全构造,因此从 D 的虚拟函数实现内部对 D 中的成员变量的任何访问都将访问未初始化的内存。

How could an abstract base class's constructor be used for anything?

Suppose you have an abstract base class B and a derived class D. When an object of type D is created, B's constructor is called first, but at that point, the object "is" still of type B (see here) -- in particular, calling any virtual functions from the body of B's constructor will call B's own implementations of those functions. But if B is a pure abstract class, none of those virtual functions are defined, so the program will crash immediately.

I'm guessing that you intended for B's constructor to call down to the most-derived-class's (e.g. D's) implementation of a virtual function, right? That would be a bad idea in general because D's object is not fully constructed yet, so any accesses to member variables in D from inside D's implementation of the virtual function would access uninitialised memory.

别忘他 2024-07-18 07:10:46

请记住:“资源获取就是初始化”

有时我们使用抽象基类作为某种锁定机制。 例如,在多线程环境中,多个线程需要共享单个资源,那么线程可以使用构造函数作为获取资源的方式,并使用析构函数来释放资源

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

Remember: "Resource acquisition is initialization".

Sometimes we use abstract base classes as some kind of locking mechanism. For example, in a multi-threaded environment, where several threads need to share a single resource, then a thread can use the constructor as a way to acquire the resource, and the destructor to release the resource

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

各自安好 2024-07-18 07:10:46

我想不出很多有用的例子。 没有数据成员的类没有状态,因此无法初始化任何内容。 不过,您可以让构造函数/析构函数为您进行日志记录。 例如,要记录所有 Visitor 对象的创建/销毁:

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;
    // ...
};

I can't think of many useful examples. A class without data-members has no state and thus can't initialize anything. You can have the constructor/destructor do logging for you, though. For example, to log the creation/destruction of all Visitor objects:

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;
    // ...
};
迷雾森÷林ヴ 2024-07-18 07:10:46

通常它只是为了让成员初始化为合理的价值观。

usually its solely to initialise members to sensible values.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文