Sean Wahl
Sean Wahl

Reputation: 19

C++: Initializing class member variable with reference to another class member variable?

I am attempting to make a class in c++ called to store values for a number of parameters that are organized as member variables of class 'Planet' and class 'Satellite', which I want to initialize with a reference to an instance of 'Planet'. Here I provide an example where I have a 'PlanetCatalog' class with member variables 'Planet neptune' and a 'Satellite triton'.

class Planet {
    public:

    double a;

    Planet() {}

    void setParams(  const double a_) {
        a = a_;
    }
};


class Satellite {
    public:

    double b;

    Planet & planet;
    Satellite( Planet & planet_):planet(planet_) { }

    void setParams(const double b_) {
        b = b_;
    }
}; 

class PlanetCatalog {

    public:

    Planet neptune;
    Satellite triton(neptune);

    void setAll() {
        neptune.setParams(1.);
        triton.setParams(2.);
    }

};

However, upon compiling I encounter the error.

error: unknown type name 'neptune' 
    Satellite triton(neptune);

Is it possible to have the Planet and Satellite stored as variables of the same class as I have done here. If not, could someone suggest a better way of organizing this functionality in c++?

Upvotes: 0

Views: 67

Answers (2)

WhiZTiM
WhiZTiM

Reputation: 21576

What happened?

class PlanetCatalog {
public:
   ...
   Planet neptune;
   Satellite triton(neptune); //<-- Compiler sees this as a non-static member-function declaration
   ...

Because of the context of that statement, the compiler sees it as a non-static member-function declaration and tries to find such type named neptune within the relevant namespace(s); It issues an error since it can't find it.


Option 1: You can define a constructor that initializes triton for you in its member-initialization-list

class PlanetCatalog {
public:
   ...
   Planet neptune;
   Satellite triton;

   PlanetCatalog() : triton(neptune) {}
   ...

Note: using this option, the order of your class data members matters, because the order initialization of data members is defined by their order of declaration in the class, not by the order of initialization in the member-initialization-list


Option 2: Another straightforward solution will be to use copy-initialization

Satellite triton = neptune;

Option 3: or list-initialization

Satellite triton{neptune};

Options 2 and 3 are preferable because it forces the declaration order implicitly.

Upvotes: 1

user7860670
user7860670

Reputation: 37468

Use of parentheses for in-class initialization makes compiler treat triton as a non-static member function declaration with neptune being type of the first argument, you should use list-initialization syntax instead:

Satellite triton{neptune};

Note that there is actually no need to define PlanetCatalog constructor for this.

Upvotes: 2

Related Questions