关于继承:为什么可以继承C ++中的接口

Why can you inherit from interfaces in C++

我有一个从C++移植到Java的应用程序。有一段C++代码我觉得很奇怪。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
typedef std::string ArgName;
typedef std::map< ArgName, AnyData > ArgumentMap;

class Arguments : public ArgumentMap
{
    public:
    // Very important note: When read finds a numeric/set argument,
    // it sets anyData.kind to Int. But STILL, it fills anyData.dString,
    // just in case. So if the ArgumentMap was built by Arguments::read,
    // the dString fields are all filled.
    bool read( int argc, char **argv );

    // remains is filled with the arguments not starting with '-'.
    bool read( int argc, char **argv, std::vector<const char*>& remains );

    // const if fails, erases arg if succeeds.
    bool getNumericParam( const ArgName& name, int& num );

    // sw is true if the switch is present. The function
    // returns false if the argument value is not empty.
    bool getSwitch( const ArgName& name, bool& sw );

    bool getSwitchConst( const ArgName& name, bool& sw ) const;

    // Returns true if the switch is present. Throws an error message if
    // if the argument value is not empty.
    bool getSwitchCompact( const ArgName& name );

    void checkEmptyArgs() const;

};

在原始C++中,作者让他们的参数类从地图继承。这对我来说毫无意义。映射是一个接口,这意味着您不能继承它,只能实现它。这是在C++中可以做的,不能用Java做的吗?

另外,我不明白为什么要使用typedef。我读了维基百科的定义

typedef is a keyword in the C and C++ programming languages. The purpose of typedef is to
form complex types from more-basic machine types[1] and assign simpler names to such
combinations. They are most often used when a standard declaration is cumbersome,
potentially confusing, or likely to vary from one implementation to another

但我不明白为什么作者会在这里这么做。他们是想说他们想从类中继承anydata,而argumentmap应该将map作为其字段之一?


This makes no sense to me. Map is an interface

在Java中,它是。在C++中,它甚至不是一个类,它是一个类模板。C++没有类似Java接口的概念,尽管可以实现与虚拟继承类似的一些东西。

就收集类而言,C++解决了模板和泛型编程,Java用接口和继承解决了什么。

C++ MAP模板的实例是完全运行的类,其类类似于Java的EDCOX1 8。您可以以与Java中的类继承相同的方式继承它们,并且由于多重继承,您不限于单个类。

Also, I don't understand why you would use a typedef.

您可以使用typedef给类赋予有意义的名称。除了缩短您的输入,它使您的程序更具可读性,并且在以后重新定义typedef后面的类时提供了更多的灵活性。

注意:您可以从标准容器继承并不意味着您应该这样做。有关详细信息,请阅读此问题的答案。


接口是特定于Java的语言结构。它们不存在于C++中。在C++中,只有类。您可以拥有抽象类(具有未实现方法的类),并且最终可以使用它们来阐明接口。


C++具有多重继承性,没有"接口"。您当然可以从任何类继承。C++有模板,Java中完全不存在模板。模板允许您让编译器编写专门定制的函数或类。


Map不是一个接口,它是一个模板。此外,作者并不是从整个Map模板派生类,而是从参数化模板派生类。没有这门课的代码,人们只能猜测他为什么要这样做,以及他想达到什么目的。

请注意,从STL模板派生通常是一个坏主意(很少有例外情况),通常最好让模板成为类的成员。模板没有virtual成员,因此在派生时没有真正的方法来改变它们的行为(在许多情况下,这是继承的真正意义)。

还有一点关于typedef:当您使用这样的typedef时,您将使代码在将来更容易更改。当您(出于任何原因)决定要实现自己的string类时,您只需要将该文件中的第一行(从typedef std::string ArgName;更改为typedef myNewStringClass ArgName;,而不需要在ArgName发生的所有地方更改代码。