我什么时候需要匿名类C++
When do I need anonymous class in C++?
C++中有一个叫做匿名类的功能。这与 C 中的匿名结构类似。我认为这个功能是因为某些需要而发明的,但我无法弄清楚那是什么。
我可以举一些真正需要匿名类的例子吗?
该功能之所以存在,是因为struct
和class
是一回事 - 你可以用一个做什么,你可以用另一个做。它与 C 中的匿名struct
完全相同;当您想要将某些内容组合在一起并声明它的一个或多个实例时,但不需要按名称引用该类型。
它在C++中不太常用,部分原因是C++设计往往更面向类型,部分原因是您无法为匿名类声明构造函数或析构函数。
严格意义上并不是真正需要的,而且从来没有。 也就是说,您始终可以分配一个名称,例如anonymous1
,anonymous2
等。但是跟踪比必要更多的名称总是很麻烦。
有用的地方是在任何想要对数据进行分组而不为该组命名的地方。我可以举几个例子:
class foo {
class {
public:
void validate( int x ) { m_x = x; }
bool valid() { return m_exists; }
private:
int m_x;
bool m_exists;
} maybe_x;
};
在这种情况下,int
和bool
在逻辑上属于一起,因此将它们分组是有意义的。但是,对于此具体示例,创建实际的可选类型或使用可用类型之一可能是有意义的,因为此模式很可能也在其他地方使用。在其他情况下,这种分组模式可能非常特殊,以至于它只应该留在该类中。
不过,我确实假设匿名类很少使用(我一生中可能只使用过几次)。通常,当想要对数据进行分组时,这不是特定于类或范围的,而是一种分组,这在其他地方也很有意义。
也许有时制作嵌套函数会有所帮助,例如:
void foo() {
class {
void operator()(){
}
} bar;
bar();
}
但是现在我们有 lambda,匿名类只是出于兼容性原因而保留。
使用匿名类是为了保持与现有 C 代码的兼容性。例:
在某些 C 代码中,将 typedef 与匿名结构结合使用很普遍。
有一个匿名结构的例子,可以与Qt 5的Signal/Slot系统一起使用,具有任何类,并且没有QObject导数要求:
void WorkspaceWidget::wwShowEvent()
{
//Show event: query a reload of the saved state and geometry
gcmessage("wwShowEvent "+ this->title());
struct{void* t; void operator()(){ static_cast<WorkspaceWidget*>(t)->wwReloadWindowState(); }}f;
f.t=this;
QObject::connect( &reloadStateTimer, &QTimer::timeout, f);
reloadStateTimer.start();
}
void WorkspaceWidget::wwReloadWindowState()
{
gcmessage( dynamic_cast<QObject*>(this)->metaObject()->className());
}
基本上,我需要将定时器信号连接到非 QObject 派生类,但希望正确传递 mt"this"。
QObject::connect 可以连接到 Qt 5 中的普通函数,所以这个匿名类实际上是一个函子,它保留了 this 指针本身,仍然传递时隙连接。
您也可以在匿名中使用 auto 执行操作 (vs2015)
struct {
auto* operator->() {return this;}
//do other functions
} mystruct;
- 什么时候调用组成单元对象的析构函数
- 什么时候在C++中返回常量引用是个好主意
- 什么时候调用析构函数
- boost odeint什么时候真正调用观测者
- 编译器对数组声明大小的计算。什么时候发生?
- 什么时候最好在子进程中使用 CPU 或 I/O 密集型代码 [ C++ ]
- 您应该在什么时候创建自己的异常类型
- 我什么时候会默认(而不是删除)基类中的复制和移动操作
- 什么时候可以使用常量装饰调用我的重载函数?
- unordered_map什么时候返回 -1?
- QCoreApplication什么时候有效?
- sizeof(size_t) 和 sizeof(ptrdiff_t) 什么时候会有所不同?
- 什么时候用指针调用C++类构造函数
- 我不明白在这个例子中什么时候调用构造函数
- 如果真的需要std::move,我们应该什么时候声明右值refs
- P1008("prohibit aggregates with user-declared constructors")在实践中什么时候有用?
- 程序什么时候会创建多个堆
- 调用boost.asio的异步函数时,线程是什么时候创建的
- Swig/python : 什么时候需要 SWIG_init() ?
- 什么时候 std::initializer_list 是微不足道的可构造的?