C ++中空类的优点

时间:2010-10-27 15:59:01

标签: c++ class

有一个空课的可能的优点/用途是什么?

P.S: 对于你们中的一些人来说,这个问题可能听起来微不足道,但这只是出于学习目的而没有实际意义。仅供参考的谷歌搜索没有帮助。

9 个答案:

答案 0 :(得分:20)

一种用途是模板(元)编程:例如,iterator tags被实现为空类。这里唯一的目的是在编译时传递信息,以便检查迭代器是否传递到例如模板功能符合特定要求。

示例:

这是真的简化,只是为了一个想法。这里标记类的目的是决定使用哪种算法实现:

class forward_iterator_tag {};
class random_access_iterator_tag {};

class MySimpleForwardIterator {
public:
  typedef typename forward_iterator_tag tag;
  // ...
};

class MySimpleRandomIterator {
public:
  typedef typename random_access_iterator_tag tag;
  // ...
};

template<class iterator, class tag>
void myfunc_int(iterator it, tag t) {
  // general implementation of myfunc
}

template<class iterator>
void myfunc_int<iterator, forward_iterator_tag>(iterator it) {
  // Implementation for forward iterators
}

template<class iterator>
void myfunc_int<iterator, random_access_iterator_tag>(iterator it) {
  // Implementation for random access iterators
}

template<class iterator>
void myfunc(iterator it) {
  myfunc_int<iterator, typename iterator::tag>(it);
}

(我希望我能做到这一点,因为我使用了它已经有一段时间......)

使用此代码,您可以在任意迭代器上调用myfunc,并让编译器根据迭代器类型(即标记)选择正确的实现。

答案 1 :(得分:5)

以下内容可用于拥有boost::variant,例如可以保存(SQL)NULL值。

class Null { };

typedef boost::variant<Null, std::string, int> Value;

为了使其更有用,operator==operator<<之类的内容非常方便。例如:

std::ostream& operator<<(std::ostream &lhs, const Null &rhs)
{
     lhs << "*NULL*";
     return lhs;
}

int main()
{
    Variant v("hello");
    std::cout << v << std::endl;
    v = Null();
    std::cout << v << std::endl;
    ...
}

会给:

hello
*NULL*

答案 2 :(得分:2)

在STL,C ++的标准模板库中,例如你有

template<class _Arg,
 class _Result>
struct unary_function
    { // base class for unary functions
 typedef _Arg argument_type;
 typedef _Result result_type;
    };

定义仿函数时,可以继承unary_function,然后自动定义typedef。

答案 3 :(得分:1)

空类可以用作定义独特内容的“标记”;在某些模式中,您需要一个与实现无关的唯一实例表示,除了它的唯一性之外,它对开发人员没有任何价值。一个例子是工作单位;你可能不在乎你的表演者内部发生了什么,但是你想告诉那个表演者你告诉它要执行的任务是原子集的一部分。在这种情况下,代表外部世界的工作单位的空类可能是完美的;几乎所有工作单元对象都可以存储或执行(封装数据库事务,暴露提交/回滚行为)会开始将您绑定到特定实现,但是对象引用对于提供对原子的唯一但可复制和可传递的引用很有用。任务集。

答案 4 :(得分:1)

您可以像占位符一样使用它来检查目的或启用特殊功能。例如,在Java中存在“空”接口Serializable,用于指定类是否可序列化。

答案 5 :(得分:0)

“empty”类是指没有数据成员的类? 它们通常声明typedef或成员函数,您可以使用自己的类扩展它们。

答案 6 :(得分:0)

Here是一个有趣的链接,解答了为什么允许它。您可能会发现这有助于找到可能有用的情况。

答案 7 :(得分:0)

正如其他人所说,通常使用占位符,区分符号,标记等空类(或结构)。

例如,很多人都不知道有newh的“nothrow”版本。调用 nothrow new 的语法是:

p = new(std::nothrow) Bar;

和std :: nothrow简单地定义为

struct nothrow_t {}; //defined in namespace std

答案 8 :(得分:0)

MartinStettner的答案很好,但只是为了强调一个重点:迭代器标签的概念或者C ++中的任何标签,并不严格依赖于空类。如果stl编写者想要的话,C ++标签很可能是非空类;应该工作,但它不会添加任何额外的价值;至少对于它通常意味着的编译时间杂技。