Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++中是否只有一个类只包含默认成员? 类的成员默认为C++中的私有。_C++_Class_Private_Private Members_Private Methods - Fatal编程技术网

C++中是否只有一个类只包含默认成员? 类的成员默认为C++中的私有。

C++中是否只有一个类只包含默认成员? 类的成员默认为C++中的私有。,c++,class,private,private-members,private-methods,C++,Class,Private,Private Members,Private Methods,因此,我想知道是否有可能创建一个将其所有成员变量和函数默认设置为private的类 换句话说,是否存在没有任何关键字public、protected或private的有意义的类定义?良好做法?可能不会,但这里有: class DataContainer { friend class DataUser; int someDataYouShouldNotWorryAbout; }; class DataUser { public: DataUser() {

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


换句话说,是否存在没有任何关键字public、protected或private的有意义的类定义?良好做法?可能不会,但这里有:

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

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

有一种模式,用于访问保护,基于这种类型的类:有时也称为see和

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


标签发送。它用于标准库中,以便选择对某些迭代器类别更有效的算法。例如,std::distance的实现方式可能如下:事实上,它在gnu libstdc++中的实现方式几乎与此完全相同,但为了提高可读性,我对其进行了一些修改


其中uu distance是一个重载函数,它可以更有效地处理std::random\u access\u iterator\u标记,它是一个空结构,但也可以很容易地成为一个类,只需使用last-first,而不是默认的计算从第一到最后所需增量的行为。

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

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

另一方面,如果您使用struct而不是class来定义一个类,那么您可以将所有内容都公开。这也许有道理

例如:

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

应用程序范围的资源获取

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

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


运行库中有一个bug。实际上,修复有问题的代码会导致其他问题,因此我编写了一个例程,找到有问题的代码片段,并将其替换为一个有效的版本。最初的化身除了它的创造之外没有任何接口。

你是指C-tor和d-tor是私有的吗?如果是,我看不到任何设计模式会使用这样的类。该类接口是完全隐藏的,因此任何人都无法从中创建对象it@NirMH一个朋友类/函数可以做到这一点。为什么你认为一定有这样一个类?“默认私有”并不意味着所有成员都应该是私有的,只是隐私应该是默认的。我想这只是为了鼓励封装。与struct相比,至少给类说明符赋予了别名以外的一些含义:我认为其目的类似于在iptables中使用默认的拒绝规则。有选择地公开您需要的内容,默认情况下隐藏所有其他内容。这是为了安全和稳定。外部事物不应该修改内部状态,理想情况下,除非通过成员函数。这并不能真正回答问题-标签根本没有成员。所有私有成员的问题是您有不可接触的状态。@MSalters:是否存在没有任何关键字public、protected或private的有意义的类定义?-标记或任何其他没有成员的类符合该描述。也许OP假设示例中会有一个或多个成员,也许是因为他没有想到空类可能有用,但在他声明之前,我认为这确实回答了问题。我没有明确声明,我发现这个例子也非常有趣。@T_at'Ghent我想到了一个工业应用程序,程序运行时我必须锁定一些硬件设备。@T_at'Ghent这段代码的目的似乎是演示这样一个对象的生命周期。你需要用你的想象力来填充正在使用的资源。我认为不可能用私有析构函数创建一个对象,因为12.4;11如果类类型的对象。。。声明,并且在声明时无法访问该类的析构函数,但此示例显示,C声明类型的唯一对象可能位于类定义本身内部。为了确保所有方法都是私有的,还应该显式声明或删除其他特殊成员函数。谢谢大家的评论。第一个版本可能值得一些解释,但我很匆忙。所以我今天早上花了一些时间来详细阐述一下。@MarcvanLeeuwen我没有考虑规范的相关部分,但是,据我所知,在声明静态数据成员时可以访问私有成员。因此,可以使用私有构造函数初始化静态对象。甚至使用私人静态工厂。甚至可以在对象的ini处调用私有方法
tialization站点,使用fluent界面。我对答案进行了编辑,以显示这种可能性。创建一个没有公共成员变量和/或函数的类是没有意义的-不完全正确,只有受保护成员的类可能有助于从中继承。@WojtekSurowka不确定如何处理接口,无法访问谁的成员函数。这个问题也禁止使用受保护的。也许可以,但我喜欢单元测试我的代码,这需要公共访问。
struct MyHwMap {
  unsigned int field1 : 16;
  unsigned int field2 : 8;
  unsigned int fieldA : 24;
};
#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;
}
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;
}
Ctor 0x601430
Init XYZ
doThis 
doThat 
Running 
Dtor0x601430