Phorce
Phorce

Reputation: 2664

C++ calling objects from another class

I asked this question here: C++ Method chaining with classes

In essesance, what I am trying to do is call a Constructor/Method from another class using Method chaining. Let's say I have 2 classes:

class Signal {

    public:
      Signal() { } // constructor

      Signal& ParseSignal() { 

          // In this method I want to call 
          // the constructor "Parse()" 
      }

    protected:
       std::vector<double> data;
};

And I have another class called Parse:

class Parse {

   public:

      Parse() {
        // This is the implementation
        // I need to access the "data" contained in class "Signal

};

My main objective would be to do the following in main:

Signal s = Signal().ParseSignal();

This would then accept the signal, and, Parse this.

Someone suggested that I should use CRTP however, due to the fact that the base class (in this case Signal) has to have a template<> argument, this is not possible due to other classes inheriting.

Is there another solution to this problem?

EDIT:

I have tried the following, however, it looks like a dirty implementation and I cannot access the member variable:

class Parser {

public:

    Parser() { 
        parse();    
    }

    void parse() {
        cout << "YES";
    }
 };

 class Signal {

public:
    friend class Parser; 
    Signal() { val = 0;}

    Signal& Parse() {
        Parser::Parser();
        return *(this);
    }
protected:

    int val;

 };

Upvotes: 0

Views: 12555

Answers (2)

kfsone
kfsone

Reputation: 24249

You implicitly cannot and should not do what you appear to be trying to do, which is to call the constructor of a class without constructing an instance of the class.

If you want the behavior of Parser in Signal, then you have at least three options: 1. Inherit Parser, 2. Add a Parser member, 3. Create a "Parseable" interface-class which Parser can take as an argument.

class Parser {
public:
    class Interface {
    public:
        std::vector<double> m_data;
    };

    Parser(Interface& interface) {
        parse(interface);
    }
};


class SignalInheriting : public Parser::Interface {
public:
    SignalInheriting() {
        Parser p(*this); // can take the Parser::Interface view of this object.
    }
};

class SignalMember {
    Parser::Interface m_parserIface;
public:
    SignalMember() : m_parserIface() {
    }
};

Doing heavy lifting in constructors like this is great for obfuscated or dog-show code, but is terrible for production systems that require any kind of maintenance.

But if you're fine with having to diagnose problems in code that works hands-free like this at 3am on a Saturday when you're hung over - then go for it.

A major factor to which pattern you should choose is how long the parse-related data is going to persist vs how long the Signal objects are going to persist.

Conversely, if the Signal object is little more than a specialization of the "Parse" API, then just inherit Parse and be done with.

Upvotes: 4

Fozi
Fozi

Reputation: 5135

The simplest way to do what you are trying to do would be something like this:

class Parse {
public:
    Parse(std::vector<double> &data) {
        // do stuff
    }
};

class Signal {
public:
    Signal() { } // constructor

    Signal& ParseSignal() { 
        Parse parser(data);
        return *this;
    }

protected:
    std::vector<double> data;
};

However I suggest that you take a look at the Visitor Pattern for a more generic solution.

Or at the very least don't do the work in the Parse constructor, do it in some method instead.

Upvotes: 3

Related Questions