user2089851
user2089851

Reputation: 151

How to compile a C++ interface that's in a header file only

I have a class Event and a subclass ServerEvent, however the Event class is only an interface for ServerEvent to extend/inherit from. When I run make an Event.o isn't generated and I get an error that it doesn't exist.

What's the right way to compile this interface and what to add in the makefile? Also, the reason I have a protected constructor is so that Event can't be instantiated. I couldn't use a virtual constructor - what is the normal way to go about inheritance?

EDIT: including the makefile, ServerEvent.cpp and compile error now

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;

}

makefile

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)

compile error

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

Upvotes: 1

Views: 4756

Answers (3)

yzhang
yzhang

Reputation: 134

  1. This is a concrete base class, it has data members so it is not an 'interface'. An 'interface' class refers to a class with no data member and all member functions are pure virtual in a sense.
  2. You #include the .h in a .cpp file and compile that .cpp file (but I don't see why you are going to do that, you must #include"Event.h" in the ServerEvent .cpp, right?)
  3. Usually, to make an interface class inheriable but non-instantiable is to use pure virtual dtor, e.g. virtual ~Event() = 0; However, this doesn't apply to your case due to my point 0. Protected ctor is probably the right way for your case, but I have to say it doesn't look like an elegant (or right) design ...

Upvotes: 2

phoeagon
phoeagon

Reputation: 2088

A class with a protected or private constructor only could not be instantiated.

Of course you can compile it if you write the implementations (EDIT: if you have the header file only there is no such thing as compiling a header file), you just cannot get an instance of Event because it is abstract in the sense that it has got only protected or private constructor.

To instantiate an instance, write a class derived from Event that has a public constructor and no pure virtual function whatsoever.

(Why on earth would you like to instantiate an abstract class anyway? If you need to instantiate it, don't define it as abstract.)

Constructors cannot be virtual because virtual functions are invoked according to a pointer table associated with the classes (including derived ones). When a constructor is invoked, that instance is not yet constructed and no virtual function can be invoked. But constructors of the derived class will call the constructor of its base class implicitly.

Upvotes: 1

Wallace Panter
Wallace Panter

Reputation: 17

As far as I know, you do not need the constructor. You need a virtual destructor, and any methods you need to implement need to be equal to 0 and virtual.

Look here: How do you declare an interface in C++?

Upvotes: 0

Related Questions