一个类是否有用于仅包含(默认情况下)c ++中的私有成员?

mr_*_*r_T 25 c++ private class private-members private-methods

默认情况下,类的成员在c ++中是私有的.

因此,我想知道是否有任何可能的用法来创建一个将其所有成员(变量和函数)默认设置为private的类.

换句话说,没有任何关键字是否存在任何有意义的类定义public,protected或者private

man*_*lio 25

有一种模式,用于访问保护,基于这种类:有时它被称为密码模式(另请参阅清洁C++粒度朋友等价?(答案:Attorney-Client Idiom)以及如何命名这种面向密钥的访问保护模式?).

只有密钥类的朋友才能访问protectedMethod():

// All members set by default to private
class PassKey { friend class Foo; PassKey() {} };

class Bar
{
public:
  void protectedMethod(PassKey);
};

class Foo
{
  void do_stuff(Bar& b)
  {
    b.protectedMethod(PassKey());  // works, Foo is friend of PassKey
  }
};

class Baz
{
  void do_stuff(Bar& b)
  {
    b.protectedMethod(PassKey()); // error, PassKey() is private
  }
};
Run Code Online (Sandbox Code Playgroud)


Ben*_*ley 18

标签调度.它在标准库中用于迭代器类别标记,以便选择对某些迭代器类别更有效的算法.例如,std::distance可以实现类似这样的事情:( 实际上它在gnu libstdc ++中实现的几乎完全相同,但我稍微修改了它以提高可读性)

template<typename Iterator>
typename iterator_traits<Iterator>::difference_type
distance(Iterator first, Iterator last)
{
      return __distance(first, last,
             typename iterator_traits<Iterator>::iterator_category());
}
Run Code Online (Sandbox Code Playgroud)

哪里__distance是超载更有效地对行为的功能std::random_access_iterator_tag (这是一个空的结构,但也很容易成为一类),简单地使用last - first,而不是计算需要多少增量获得的默认行为firstlast.

  • @MSalters:*"是否存在任何有意义的类定义而没有任何关键字public,protected或private?"* - 标签或任何其他没有成员的类符合该描述.也许OP假设示例会有一个或多个成员(也许是因为他没有想到空类可能有用),但直到他说出来,我认为这确实回答了这个问题. (8认同)
  • 没有真正回答这个问题 - 标签根本没有成员.所有私人成员的问题是你有不可触及的状态. (2认同)

Syl*_*oux 15

应用范围的资源获取?

#include <iostream>

class C {
    C() {
        std::cout << "Acquire resource" << std::endl;
    }


    ~C() {
        std::cout << "Release resource" << std::endl;
    }

    static C c;
};


C C::c;

int main() {
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

正如下面的评论中所述,我想到了一个工业应用程序,它必须在程序运行时"锁定"某些硬件设备.但人们可能会发现其他用途,毕竟,它只是一些"退化"案例或RAII.


至于在声明块之外使用"私有"方法:我在这里使用静态成员.因此,它是在私人成员可访问的地方宣布的.您不仅限于构造函数/析构函数.您甚至可以(ab)使用静态方法,然后使用流畅的接口调用私有实例方法:

class C {
    C() { std::cout << "Ctor " << this << std::endl; }
    ~C() { std::cout << "Dtor" << this << std::endl; }

    static C* init(const char* mode) {
        static C theC;

        std::cout << "Init " << mode << std::endl;
        return &theC;
    }

    C* doThis() {
        std::cout << "doThis " << std::endl;

        return this;
    }

    C* doThat() {
        std::cout << "doThat " << std::endl;

        return this;
    }

    static C *c;
};


C *C::c = C::init("XYZ")
            ->doThis()
            ->doThat();

int main() {
    std::cout << "Running " << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

该代码仍然有效(因为所有C成员都可以在声明时访问C::c).并会产生类似的东西:

Ctor 0x601430
Init XYZ
doThis 
doThat 
Running 
Dtor0x601430
Run Code Online (Sandbox Code Playgroud)

  • @T_at'Ghent我想到了一个工业应用程序,我必须在程序运行时"锁定"某些硬件设备. (4认同)
  • 我认为实际创建一个带有私有析构函数的对象是不可能的,因为12.4; 11"如果一个类类型的对象被声明,并且该类的析构函数不可访问,那么程序就会格式错误.声明",但这个例子表明它是可能的(类型`C`声明的唯一对象是在类定义本身内).为了确保_all_方法是私有的,还应该明确声明或删除其他特殊成员函数. (2认同)

Ale*_*vig 7

有意义?好的做法?可能不会,但是这里有:

class DataContainer {
    friend class DataUser;
    int someDataYouShouldNotWorryAbout;
};

class DataUser {
public:
    DataUser() {
        container.someDataYouShouldNotWorryAbout = 42;
    }
private:
    DataContainer container;
};
Run Code Online (Sandbox Code Playgroud)