C++:对用户隐藏类构造

Posted

技术标签:

【中文标题】C++:对用户隐藏类构造【英文标题】:C++: hide class construction from user 【发布时间】:2013-05-24 02:11:22 【问题描述】:

我正在开发一系列事件类。这些类包含从系统获取的信息。它们来自不同的性质,可能包含不同的消息,例如:一个可能的事件将包含一个巨大的数字列表,而另一个将携带字符串形式的查询信息。我想创建一个构建器函数来创建正确类型的事件并返回给用户。

下面是它的外观演示:

main.cpp:

#include <iostream>

#include "A.h"
#include "dA.h"

using namespace std;

int main()


   cout << "Hello world!" << endl;

   A a = build(5);

   return 0;

事件.h:

#ifndef A_H_INCLUDED
#define A_H_INCLUDED

#include <iostream>

class A

public:
    friend A build(int x);
protected:
    A(int x);
private:
;
#endif // A_H_INCLUDED

event.cpp:

#include "A.h"

A::A(int x)

    
        std::cout << "A\n";
        std::cout << x << std::endl;
    


A build(int x)

    if(x == 5)
        return dA(x);
    return make(x);

特殊事件.h

#ifndef DA_H_INCLUDED
#define DA_H_INCLUDED

#include <iostream>

#include "A.h"

class dA : public A

public:
protected:
    dA(int x);
;

#endif // DA_H_INCLUDED

特殊事件.cpp:

#include "dA.h"

dA::dA(int x) : A(x)

    std::cout << "dA\n";

如您所见,所有构造函数都受到保护,其目的是对用户隐藏构造—​​—(s)他不应该从无到有创建事件,只有系统可以——并保证构建函数将返回正确的事件类型。

编译时,我得到:

error: 'build' was not declared in this scope
warning: unused variable 'a' [-Wunused-variable]

如果我把所有东西放在同一个文件中,我可以编译,但是,我最终会得到一个难以管理的大文件。注意上面的代码只是一个例子,我要使用的真实类是巨大的,放在同一个文件中,无论是声明还是实现,一切都变得一团糟。

【问题讨论】:

从 Joachim 的回答中遇到的错误来看,我的建议是将它们全部放入一个文件中。这样一来,如果您没有正确构建,或者实际上存在编码错误,您就可以隔离。 【参考方案1】:

您必须声明build 函数。现在,您只告诉编译器它是 Afriend,但您没有在全局范围内声明它。

只需在A.h 头文件中添加一个原型即可:

A build(int x);

您似乎没有正确地将文件链接在一起。您似乎正在使用 GCC(根据错误消息判断),您可以通过两种方式进行:

    将编译和链接合二为一:

    $ g++ main.cpp event.cpp -Wall -g -o my_program
    

    在上述命令中,您告诉 GCC 编译文件 main.cppevent.cpp 并将它们链接在一起,生成 my_program 可执行文件。标志-Wall 启用更多警告(这很好,我个人使用更多选项来启用大量警告),-g 告诉 GCC 包含调试信息。

    第二种方法是将文件分别编译成目标文件,然后在单独的步骤中将这些目标文件链接在一起:

    $ g++ main.cpp -c -Wall -g
    $ g++ event.cpp -c -Wall -g
    $ g++ main.o event.o -o my_program
    

    新标志-c 告诉 GCC 生成一个与源文件具有相同基本名称的目标文件,因此对于main.cpp,它将被命名为main.o。然后最后一个命令获取这些目标文件并将它们链接到可执行文件my_program

如果您有很多源文件,则首选第二种方式,就像您对单个源文件进行更改一样,您不必重新编译所有这些文件,只需对您更改的那个文件进行编译。由于一直手动编写这些命令可能需要大量工作,因此建议使用 make 等工具来自动执行这些任务。

【讨论】:

我试过了,我得到了这个:main.o||在函数main':| main.cpp|12|undefined reference to build(int)'| ||=== 构建完成:1 个错误,0 个警告(0 分钟,0 秒)===| @Fred 那么你不要链接event.cpp文件。 @Fred 用有关如何编译和链接多个源文件的信息更新了我的答案。 我使用代码块作为 IDE,它会自动完成所有这些。它用mingw编译。我仍然不知道如何添加 -c 标志,但我会尝试你的建议。感谢您的关注。

以上是关于C++:对用户隐藏类构造的主要内容,如果未能解决你的问题,请参考以下文章

c# 中不可能隐藏构造函数的嵌套类?

如何在 C++ 中隐藏一个类?

C++ 封装 & 信息隐藏

C++ 隐藏继承层次结构中的成员函数,紧盯 CRTP

1.封装,构造,重载,静态常量

隐藏实用程序类构造函数:实用程序类不应具有公共或默认构造函数