对我来说,创建抽象类DataType的最佳方法是什么?

时间:2018-12-30 19:16:32

标签: c++ inheritance abstract-class

自从我使用了类似C的语言(包括C ++)以来,已经很长一段时间了。我目前的工作主要是专注于Python,而C ++处理继承的方式使我有些沮丧。我需要能够读取日志文件并根据预定义的模式提取重要的信息,以在上述日志中查找。

我有一个抽象类DataType

#include <string>

using namespace std;

class DataType {
public:
    // Getters
    virtual string GetRawData() const;
    virtual string GetFormattedData() const;

protected:
    // Transform raw data (if possible)
    virtual int Transform(string raw, string &fmt) = 0;

    // A pattern string (regex) to compare against raw_data to see
    // if can be transformed into a normalized format
    static string definition;

    string raw_data;
    string formatted_data;

};

您可以通过纯虚函数Transform()看到,我不希望此类可以实例化。我将为此创建子类:IPv4AddressIPv6AddressTimestamp,等等。

我很确定我正在慢慢掌握虚函数并在派生类中重载它们。但是,我仍在努力如何最好地处理成员变量(definitionraw_dataformatted_data)。特别是对于definition,我真的希望所有派生类都具有自己的值,但是对于每个类,该变量应该是静态的。我的问题是在哪里声明,在在哪里定义?

当我在IPv4Address.h中定义IPv4Address时,我的派生类definition所处的状态如下:

class IPv4Address : public DataType {
//stuff above
protected:
    // I know the pattern doesn't work matching IP addresses.
    // I'm just trying to get this to compile without error for now.
    static string definition = "[a-zA-Z_][a-zA-Z_0-9]*\\.[a-zA-Z0-9]+";
//stuff below
}

我收到此错误:

in-call initialization of static data member 'std::__cxx11::string IPv4Address::definition of non-literal type

我是否需要在cpp文件中定义此变量?这对我来说似乎不对,但这并不意味着什么。感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

通常在C ++中,静态数据成员必须在类外部(通常在.cpp文件中)定义,如下所示:

string IPv4Address::definition = "[a-zA-Z_][a-zA-Z_0-9]*\\.[a-zA-Z0-9]+";

但是,对于您而言,根本不需要此数据成员,尤其是在您的基类DataType中。数据成员不能在派生类中被覆盖,因此当您在definition类中声明DataType成员并在IPv4Address类中“重新定义”它时,您实际上定义了两个单独的不相关的变量,这将无济于事您可以根据类类型以任何方式使用不同的模式。例如:

void foo(DataType &data)
{
    cout << data.definition; // assuming "definition" is public for the sake of example
}

void bar()
{
    IPv4Address addr;
    foo(addr); // will output the DataType::definition and not IPv4Address::definition because the "definition" data member is not "virtual" and there is really no such thing
}

鉴于您的Transform方法将是使用此definition的方法,并且在每个类中都会有所不同,因此您可以完全摆脱此数据成员,只需将其作为{的一部分{1}}的定义。