通过函数传递未命名的类

时间:2009-06-13 17:09:30

标签: c++ oop class

如何将此实例作为参数传递给函数?

class
{
    public:
    void foo();
} bar;

我必须为班级命名吗? 它是可复制的,因为我没有让班级的副本ctor私有 那怎么可能呢?

4 个答案:

答案 0 :(得分:6)

如果你明确表达你想做的事情,也许会更好。你为什么要创建一个未命名的类?它符合界面吗?未命名的类是非常有限的,它们不能用作函数的参数,它们不能用作模板类型参数......

现在,如果你正在实现一个接口,那么你可以传递对该接口的引用:

class interface {
public:
   virtual void f() const = 0;
};
void function( interface const& o )
{
   o.f();
}
int main()
{
   class : public interface {
   public:
      virtual void f() const {
         std::cout << "bar" << std::endl;
      }
   } bar;
   function( bar ); // will printout "bar"
}

注意:对于将模板参数视为选项的所有答案,未命名的类不能作为模板类型参数传递。

C ++标准。 14.3.1,第2段:

  

2本地类型,没有类型   链接,未命名的类型或类型   从任何这些类型复合而成   不得用作   模板的模板参数   型参数。

如果您使用comeau编译器测试(该链接用于在线试用),您将收到以下错误:

  

错误:模板参数可能不会   引用未命名的类型

作为旁注,comeau编译器是我所知道的最符合标准的编译器,除了是我尝试过的最有用的错误诊断之一。

注意:Comeau和gcc(g ++ 4.0)给出了上面代码的错误。英特尔编译器(以及其他人的评论MSVS 2008)接受使用未命名的类作为模板参数,而不是标准。

答案 1 :(得分:2)

如果要将匿名类传递给函数,为什么要创建匿名类?

只需明确声明类:

class Foo {
  // ...
};

void Method(Foo instance); 

int main() {
    Foo bar;
    Method(bar);
}

第二种可能性是使用模板函数,因此编译器会推断出类型(请注意,这不是标准兼容的!)

#include <iostream>

using namespace std;

template <typename T>
void SayFoo(T& arg) {
    arg.Foo();
}

int main() {

    class {
    public: 
        void Foo() { cout << "Hi" << endl; }
    } Bar;

    Bar.Foo();

    SayFoo(Bar);

    return 0;
}

复制类没有问题,因为编译器会自动生成复制构造函数,您可以使用boost::typeof之类的工具来避免明确引用类型。

BOOST::AUTO(copy, Bar);

另一个approch正在使用(相对较慢)运行时多态(接口/继承)。

答案 2 :(得分:0)

是的,您必须将该类命名为将该实例传递给该函数。由于您没有提供自己的副本,因此ctor编译器将生成自己的副本并使用它。

答案 3 :(得分:-1)

嗯,无名的课。

您可以将指针传递给它* void *。

由于您无法通过名称引用它,因此除了一个实例之外,您无法调用其构造函数,复制构造函数或析构函数,因此您无法复制它。

编辑:您仍然可以将其传递给可以复制它的模板函数。

REEDIT:编辑错误。