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

时间:2014-09-11 10:27:34

标签: c++ class private private-members private-methods

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

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

换句话说,如果没有任何关键字publicprotectedprivate,是否存在任何有意义的类定义?

6 个答案:

答案 0 :(得分:25)

有一种用于访问保护的模式,基于这种类:有时称为passkey pattern(另请参阅clean C++ granular friend equivalent? (Answer: Attorney-Client Idiom)How to name this key-oriented access-protection pattern?)。

只有密钥类的朋友才能访问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
  }
};

答案 1 :(得分:18)

标签调度。它在iterator category tags的标准库中使用,以便选择对某些迭代器类别更有效的算法。例如,std::distance可以实现如下:(事实上它在gnu libstdc ++中实现的几乎完全相同,但我已经稍微修改它以提高可读性) < / p>

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

__distance是一个重载的函数,可以更有效地处理std::random_access_iterator_tag (这是一个空结构,但可以很容易成为一个类),只需使用last - first代替计算将first转换为last所需的增量的默认行为。

答案 2 :(得分: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;
}

正如下面的评论中所述,我想到了一个工业应用程序,它必须在程序运行时“锁定”某些硬件设备。但有人可能会发现其他用途,因为毕竟只有一些“堕落”的情况或RAII


关于在声明块之外使用“private”方法:我在这里使用静态成员。因此,它是声明,其中私有成员可访问。您不仅限于构造函数/析构函数。您甚至可以(ab)使用静态方法,然后使用fluent interface调用私有实例方法:

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;
}

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

Ctor 0x601430
Init XYZ
doThis 
doThat 
Running 
Dtor0x601430

答案 3 :(得分:7)

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

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

class DataUser {
public:
    DataUser() {
        container.someDataYouShouldNotWorryAbout = 42;
    }
private:
    DataContainer container;
};

答案 4 :(得分:1)

不,创建没有公共成员变量和/或函数的类是没有意义的,因为没有办法访问类中的任何内容。即使没有明确说明,继承也是私有的。

当然,您可以按照建议使用friend,但会产生不必要的卷积。


另一方面,如果您使用struct而不是class来定义课程,那么您可以将所有内容公开。这可能是有道理的。

例如:

struct MyHwMap {
  unsigned int field1 : 16;
  unsigned int field2 : 8;
  unsigned int fieldA : 24;
};

答案 5 :(得分:0)

许多年前的一个公认的丑陋案例,而不是C ++,但这个想法仍然适用:

运行时库中存在错误。实际上修复有问题的代码会导致其他问题,所以我编写了一个例程,找到了令人讨厌的代码并将其替换为有效的版本。原始的化身除了它的创造之外根本没有界面。