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

时间:2013-05-24 02:11:22

标签: c++ inheritance c++11 friend

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

以下是它的外观演示:

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

Event.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);
}

特别活动。

#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

特殊event.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]

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

1 个答案:

答案 0 :(得分:1)

您必须声明build功能。现在,您只告诉编译器它是friend的{​​{1}},但您没有在全局范围内声明它。

只需在A标题文件中添加原型:

A.h

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

  1. 将编译和链接合并为一步:

    A build(int x);
    

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

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

    -g

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

  3. 如果您有很多源文件,则首选第二种方式,就好像您对单个源文件进行更改一样,您不必再次编译所有源文件。由于手动编写这些命令可能需要做很多工作,因此建议使用make等工具自动完成这些任务。