为什么C++类可以没有数据成员?

hs1rzwqc  于 2022-12-24  发布在  其他
关注(0)|答案(6)|浏览(186)

关于c++类定义中最小数据成员数为零的问题
我认为它应该是一,即指向编译器定义的虚拟表的指针
非常感谢

de90aj5v

de90aj5v1#

拥有一个没有数据成员的类以用于继承层次结构中通常很有用。
一个基类可能只有几个typedef在多个类中使用,例如,std::iterator类模板只定义了标准类型,这样就不需要在每个迭代器类中定义它们。
接口类通常没有数据成员,只有虚成员函数。
虚表与类的数据成员无关。

tvmytwxo

tvmytwxo2#

我正在开发一个库,它有时候甚至使用了-- * 喘气!* --甚至没有 * 定义 * 的类型,更不用说有数据成员了!
也就是说,类型是不完整的,例如

struct foobar;

这是用来创建一个明确的名称,仅此而已。
那么这有什么用呢?我们用它来创建不同的 tags,使用一个额外的(空的,但是完全定义的)类型:

template <typename TSpec>
struct Tag {};

现在你可以像这样创建不同的标签(是的,我们可以在模板参数列表中声明类型,而不需要单独声明):

using ForwardTag = Tag<struct Forward_>;
using RandomAccessibleTag = Tag<struct RandomAccessible_>;

这反过来又可以用来消除特殊重载的歧义。许多STL实现都做类似的事情:

template <typename Iter>
void sort(Iter begin, Iter end, RandomAccessibleTag const&) …

严格地说,通过公共Tag类模板的间接路径是多余的,但为了文档的目的,这是一个有用的技巧。
所有这些只是为了说明,(严格的、静态的)类型系统可以用于许多不同的方式,而不仅仅是捆绑和封装数据。

92dk7w1h

92dk7w1h3#

事实上,C++要求所有的类都必须占用一定的空间(你需要能够生成一个指向该类的指针),如果类是多态的,那么它们只需要一个指向vtable的指针,在单态类中根本没有必要使用vtable。

hzbexzde

hzbexzde4#

没有数据成员的类的另一个用途是处理来自其他来源的数据。所有的东西都在运行时通过指针或引用传递到类中,类对数据进行操作,但不存储任何数据。
直到我看到它在我学习的UML类中完成,我才真正考虑到这一点。它有它的用途,但它通常创建耦合类。

brc7rcf0

brc7rcf05#

因为类不是结构,它们的目的与流行的看法相反,不是用来保存数据的。
例如,考虑一个验证器基类,它定义了一个虚方法,该方法传递一个要验证的字符串,并返回一个布尔值。
验证器的一个示例可能会拒绝包含大写字母的字符串,这是一个很好的例子,说明了什么时候应该使用类,根据类的定义,显然没有理由使用任何成员变量。

5sxhfpxr

5sxhfpxr6#

关于c++类定义中最小数据成员数为零的问题
它为零是因为有各种不应该有成员的类的情况:
例如,你可以实现只包含静态函数的traits类。这些类相当于namespace,它也可以被识别为类型。这意味着你可以在类上示例化一个模板,并确保该模板的实现使用类中的函数。* 这样一个traits类的大小应该是零。*
示例:

class SingleThreadedArithmetic
{
    static int Increment(int i) { return ++i; }
    // other arithmetic operations implemented with no thread safety
}; // no state and no virtual members -> sizeof(SingleThreadedArithmetic) == 0

class MultiThreadedArithmetic
{
    static int Increment(int i) { return InterlockedIncrement(i); }
    // other arithmetic operations implemented with thread safety in mind
}; // no state and no virtual members -> sizeof(MultiThreadedArithmetic) == 0

template<class ThreadingModel> class SomeClass
{
public:
    void SomeFunction()
    {
        // some operations
        ThreadingModel::Increment(i);
        // some other operations
    }
};

typedef SomeClass<SingleThreadedArithmetic> SomeClassST;
typedef SomeClass<MultithreadedArithmetic>  SomeClassMT;

您可以通过实现"tag"类来定义不同的类类别:没有接口或数据的类,只是用来区分不同的"逻辑"类型的派生类。2这种区分可以用在普通的OOP代码或模板代码中。3这些"标签"类的大小也为0。4请参考当前STL库中的迭代器标签实现。
我确信在其他情况下您可以使用"零大小"类。

相关问题