【问题标题】:Is it possible to call a private constructor from a static method defined in the cpp?是否可以从 cpp 中定义的静态方法调用私有构造函数?
【发布时间】:2012-06-22 18:44:24
【问题描述】:

一个 C++ n00b 问题。是否可以从 cpp 中定义的静态方法调用私有构造函数?如果可能的话,我想将方法​​保留在头文件之外——我认为应该有办法做到这一点。尝试此操作时出现错误:

"不能访问类 SomeClass 中声明的私有成员"

/////////////////
// SomeClass.h //
/////////////////

class SomeClass {
    public:
        static SomeClass SomeMethod();
    private:
        SomeClass(int i);
}

///////////////////
// SomeClass.cpp //
///////////////////

static SomeClass OSImplementation() {
    return SomeClass(0);
};

// calls implementation
SomeClass SomeClass::SomeMethod() {
    return OSImplementation();
}

【问题讨论】:

  • OSImplementation 应该是朋友(假设你不能成为会员)。

标签: c++


【解决方案1】:

您可以将OSImplementation 设为好友方法。

或者您可以将OSImplementation 设为类中的静态方法(但必须在标头中声明)。

或者,可能最常见的方法是拥有一个内部实现类,如下所示:

class SomeClass {
public:
    //...
private:
    struct Impl;
    Impl* intern;
};

在您的 cpp 文件中,您声明 struct SomeClass::Impl

在您的构造函数中,创建SomeClass::Impl 实例。在析构函数中删除它。并实现复制构造函数和赋值运算符!

这称为 PIMPL(指向实现的指针)习语(Wikipediac2.com)。它在 Qt 等大型项目中被大量使用。

【讨论】:

  • 类中的静态方法(但必须在标头中定义)”你的意思是声明的,而不是定义的?
  • 有没有什么方法可以创建好友而不定义好友?也许它只会让构造函数公开:)
  • @DanielH:你不需要另外提前声明friended方法。但是,这也必须放入您的标题中。如果你有很多这样的功能,那也会变得丑陋。此外,您并没有真正从中获得任何好处,将它作为静态方法或普通成员方法可能更有意义。但是,如果你想让它真正干净,需要付出一些额外的努力,那么 PIMPL 成语就是要走的路(实际上没有其他选择)。
  • 感谢 Albert -- 非常有帮助。如何定义一个不在标题中的朋友?
  • 只需将friend SomeClass OSImplementation(); 放入您的类声明中(在标题中)。因此,friend 本身必须在标题中。
【解决方案2】:

是的,可以通过将 OSImplementation() 成为 SomeClass 的朋友来实现。下一个示例使用 g++ 4.6.1 编译时没有警告和错误:

#include <iostream>

// declare in hpp
class SomeClass {

   friend SomeClass OSImplementation();

    public:
        static SomeClass SomeMethod();

        void foo();

    private:
        SomeClass(int);
};


int main()
{
  auto obj = SomeClass::SomeMethod();

  obj.foo();
}

// define in cpp
SomeClass SomeClass::SomeMethod(){
  return SomeClass( 5 );
}

SomeClass::SomeClass(int){
}

void SomeClass::foo(){
  std::cout<<"foo"<<std::endl;
}

SomeClass OSImplementation()
{
  return SomeClass::SomeMethod();
}

【讨论】:

  • cpp中定义的静态文件方法,对类来说不是静态的。
  • @DanielH 在您的伪代码中,我只看到 SomeMethod 作为标题中的静态方法
猜你喜欢
  • 1970-01-01
  • 2021-01-26
  • 1970-01-01
  • 1970-01-01
  • 2013-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-30
相关资源
最近更新 更多