0

With the reference of this Stackoverflow question, I'm not able to figure out the same problem of implementing DI using interface in c++ style, i.e. abstract class. Instead of bumping up old thread I created this one. Compiler throws error for the last line.

class IService {
    virtual void DoWork() = 0;
    virtual bool IsRunning() = 0;
};

class ClientA : IService {
    void DoWork() {
        std::cout << "Work in progress inside A";
    }
    bool IsRunning() { 
        return true; 
    }
};

class ClientB : IService {
    void DoWork() {
        std::cout << "Work in progress inside B";
    }
    bool IsRunning() {
        return true;
    }
};

class Server {
    IService* _service;
    Server(IService* service) : _service(service)
    { }

    // Error: this declaration has no storage class or type specifier
    // Compiler: MSVC 2017
    _service->DoWork();
};
anupx73
  • 398
  • 5
  • 18
  • 1
    In C++, `class` is a definition of a (composed) data type (similar like a `struct`). It may not contain statements directly. Statements may be used only in functions (incl. member functions). – Scheff's Cat Jul 04 '17 at 05:25
  • 1
    `_service->DoWork();` is a statement inside a class but outside of any function. You can't do that in C++, no matter wheter your classes are abstract or not. – n. m. could be an AI Jul 04 '17 at 05:25
  • 1
    For future reference, we have no problem with bumping old Q/A's on Stack Overflow. OTOH, your question is distinct from that other question, so it's correct to ask this as a separate question – Justin Jul 04 '17 at 05:32
  • This has nothing to do with abstract classes or dependency injection. – juanchopanza Jul 04 '17 at 05:43

2 Answers2

3
  1. In C++ class members are private by default. You should specify public: before virtual void DoWork() = 0;.

  2. C++ inheritance is private by default (when using class keyword). Instead of : IService, try : public IService. See differences between private, protected, public inheritance here.

  3. Where is the function body of _service->DoWork();?

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
raymai97
  • 806
  • 7
  • 19
  • 1
    (1) There's no necessity to do that. A non virtual interface function often does call private virtual functions, they can still be overridden. (2) Only when using the class keyword. – StoryTeller - Unslander Monica Jul 04 '17 at 05:29
  • @StoryTeller Good catch for (2). As for (1), I assume that he want the outsider to be able to call every functions in `IService`. I thought `public` is needed here? Or am I wrong? – raymai97 Jul 04 '17 at 05:37
  • Oh, you meant to make the ISerivce functions public. Yeah, I agree. Brain hiccup, sorry. – StoryTeller - Unslander Monica Jul 04 '17 at 05:40
  • @raymai97 Holy shit!! I missed the function and basics of C++. It really a great silly mistake by me. I really apologize for this types of question. I would be definitely double check any code before posting further. Finally a huge thanks. – anupx73 Jul 04 '17 at 05:58
3

I believe this is what you wanted:

#include <iostream>
using namespace std;

struct IService {
    virtual ~IService() = default; // Remember about virtual dtor to avoid memory leaks!
    virtual void DoWork() = 0;
    virtual bool IsRunning() = 0;
};

class ClientA : public IService {
    void DoWork() {
        std::cout << "Work in progress inside A" << endl;
    }
    bool IsRunning() { 
        return true; 
    }
};

class ClientB : public IService {
    void DoWork() {
        std::cout << "Work in progress inside B" << endl;
    }
    bool IsRunning() {
        return true;
    }
};

class Server {
    IService* _service;
public:
    Server(IService* service) : _service(service)
    { }

    void doStuff() {
        _service->DoWork();
    }
};

int main() {

    ClientA a;
    ClientB b;
    Server sa(&a), sb(&b);
    cout << "ServerA: " << endl;
    sa.doStuff();
    cout << "ServerB: " << endl;
    sb.doStuff();
    return 0;
}

Ideone

You need to get yourself familiar with the concept of access specifiers in C++. See here

K. Kirsz
  • 1,384
  • 10
  • 11
  • It was one of the worst of mine that I missed function and basics of C++. It was a great learning for me that how I did this kinda silly mistake. Thank you for your kind and quick support. This days I'm hovering around C# concept and just back to C++ for some quick demo implementation and see what I did. It was a shame. – anupx73 Jul 04 '17 at 06:01