0

クラス Event とサブクラス ServerEvent がありますが、Event クラスは ServerEvent が拡張/継承するための単なるインターフェイスです。make を実行すると、Event.o が生成されず、存在しないというエラーが表示されます。

このインターフェイスをコンパイルする正しい方法と、makefile に追加するものは何ですか? また、私が保護されたコンストラクターを持っている理由は、Event をインスタンス化できないようにするためです。仮想コンストラクターを使用できませんでした。継承の通常の方法は何ですか?

編集: makefile、ServerEvent.cpp、コンパイル エラーを含む

Event.h

#ifndef EVENT_H
#define EVENT_H

#include <string>

#define EVENT_STOP 0
#define EVENT_START 1

class Event {
private:

protected:
    double time;
    std::string label;
    int type; // EVENT_START OR EVENT_STOP
    Event();

public:

};

#endif

ServerEvent.h

#ifndef SERVEREVENT_H
#define SERVEREVENT_H

#include "Event.h"
#include <vector>
class ServerEvent: public Event {
private:

public: 
    ServerEvent(std::vector<std::string> tokens);

};

#endif

ServerEvent.cpp

#include "Event.h"
#include "ServerEvent.h"
#include <cstdlib>
#include <sstream>

ServerEvent::ServerEvent(std::vector<std::string> tokens) {
    std::stringstream stream(tokens[0]);
    stream >> time;

}

メイクファイル

OBJ = correngine.o CSVManager.o CorrelationEngineManager.o ServerEvent.o
CC = g++
CFLAGS = -c -Wall -pedantic
LFLAGS = -Wall -pedantic
EXE =   correngine 

correngine : $(OBJ) 
    $(CC) $(LFLAGS) $(OBJ) -o $(EXE)

correngine.o : correngine.cpp correngine.h CSVManager.h
    $(CC) $(CFLAGS) correngine.cpp

CSVManager.o : CSVManager.cpp CSVManager.h
    $(CC) $(CFLAGS) CSVManager.cpp

CorrelationEngineManager.o : CorrelationEngineManager.cpp CorrelationEngineManager.h Event.o
    $(CC) $(CFLAGS) CorrelationEngineManager.cpp

Event.o : Event.h
    $(CC) $(CFLAGS) Event.h

ServerEvent.o: ServerEvent.cpp ServerEvent.h Event.h
    $(CC) $(CFLAGS) ServerEvent.cpp 

clean : 
    \rm *.o $(EXE)

コンパイルエラー

ServerEvent.o: In function `ServerEvent::ServerEvent(std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >)':
ServerEvent.cpp:(.text+0x11): undefined reference to `Event::Event()'
ServerEvent.o: In function `ServerEvent::ServerEvent(std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >)':
ServerEvent.cpp:(.text+0xe1): undefined reference to `Event::Event()'
collect2: ld returned 1 exit status
make: *** [correngine] Error 1
4

3 に答える 3

2
  1. これは具体的な基本クラスであり、データ メンバーを持っているため、「インターフェイス」ではありません。「インターフェイス」クラスは、データ メンバーを持たないクラスを指し、すべてのメンバー関数はある意味で純粋仮想です。
  2. .h を .cpp ファイルに #include し、その .cpp ファイルをコンパイルします (しかし、なぜそうするのかわかりません。ServerEvent .cpp に「Event.h」を #include する必要がありますよね?)
  3. 通常、インターフェイス クラスを継承可能でインスタンス化不可能にするには、純粋な仮想 dtor を使用します。たとえば、virtual ~Event() = 0; です。ただし、私のポイント 0 のため、これはあなたのケースには当てはまりません。保護された ctor はおそらくあなたのケースには正しい方法ですが、エレガントな (または正しい) デザインのようには見えないと言わざるを得ません ...
于 2013-02-20T05:44:04.250 に答える
1

protectedまたはprivateコンストラクタのみを持つクラスをインスタンス化できませんでした。

もちろん、実装を記述すればコンパイルできます(編集:ヘッダーファイルしかない場合、ヘッダーファイルをコンパイルするようなものはありません)、のインスタンスを取得することはできませEventん。またはコンストラクターのみを取得しました。protectedprivate

インスタンスをインスタンス化するEventには、パブリック コンストラクターを持ち、純粋仮想関数をまったく持たないクラスから派生したクラスを作成します。

(一体なぜ抽象クラスをインスタンス化する必要があるのでしょうか?インスタンス化する必要がある場合は、それをabstractとして定義しないでください。)

仮想関数はクラス (派生クラスを含む) に関連付けられたポインター テーブルに従って呼び出されるため、コンストラクターを仮想にすることはできません。コンストラクターが呼び出されると、そのインスタンスはまだ構築されておらず、仮想関数を呼び出すことはできません。ただし、派生クラスのコンストラクターは、その基本クラスのコンストラクターを暗黙的に呼び出します

于 2013-02-20T05:41:23.653 に答える
0

私の知る限り、コンストラクターは必要ありません。仮想デストラクタが必要であり、実装する必要があるメソッドはすべて 0 および仮想である必要があります。

こちらをご覧ください: C++ でインターフェイスを宣言するにはどうすればよいですか?

于 2013-02-20T05:39:29.073 に答える