1

I have two class definitions, Class1 and Class2. I need to create an instance of Class1, then store that instance in an instance of Class2 so that the Class1 instance can be accessed from within the Class2 instance. I'm very new to C++ and can't seem to accomplish this.

This is my code:

main.cpp

#include <iostream>

#include "class_1.h";
#include "class_2.h";

using namespace std;

int main()
{
    cout << "Creating class 1..." << endl;

    // create class1, seems to work fine
    Class1 class1(5);

    cout << "Passing class 1 to class 2..." << endl;

    // i want to create class2, and pass the class1 instance of Class1
    // so it can be stored and accessed by Class2
    Class2 class2(class1);

    return 0;
}

class_1.h

class Class1
{
    private:

    public:

        // some variable we can store and access
        int this_x;

        // constructor
        Class1(int x);
};

class_1.cpp

#include "class_1.h"

// in the constructor set value of this_x to x
Class1::Class1(int x)
{
    this_x = x;
}

class_2.h

#include "class_1.h"

class Class2
{
    private:

        // declare the variable that I want to store Class1 in
        Class1 stored_class;

    public:

        // constructor, will receive a Class1 object instance
        Class2(Class1 store_class_1);

};

class_2.cpp

#include "class_2.h"

// constructor for Class2, takes a Class1 object
Class2::Class2(Class1 storeClass1)
{

    // i want to store storeClass1,
    // but havent got that far yet

    int y = 3;

}

I'm getting an error in the file "class_2.cpp" on the line:

Class2::Class2(Class1 storeClass1)

The compiler says

||=== Build: Debug in link_objects (compiler: GNU GCC Compiler) ===| C:\Users\Geoff\Desktop\Py Projects\link_objects\class_2.cpp||In constructor 'Class2::Class2(Class1)':| C:\Users\Geoff\Desktop\Py Projects\link_objects\class_2.cpp|7|error: no matching function for call to 'Class1::Class1()'| C:\Users\Geoff\Desktop\Py Projects\link_objects\class_1.h|18|note: candidate: 'Class1::Class1(int)'| C:\Users\Geoff\Desktop\Py Projects\link_objects\class_1.h|18|note: candidate expects 1 argument, 0 provided| C:\Users\Geoff\Desktop\Py Projects\link_objects\class_1.h|7|note: candidate: 'constexpr Class1::Class1(const Class1&)'| C:\Users\Geoff\Desktop\Py Projects\link_objects\class_1.h|7|note: candidate expects 1 argument, 0 provided| C:\Users\Geoff\Desktop\Py Projects\link_objects\class_1.h|7|note: candidate: 'constexpr Class1::Class1(Class1&&)'| C:\Users\Geoff\Desktop\Py Projects\link_objects\class_1.h|7|note: candidate expects 1 argument, 0 provided| C:\Users\Geoff\Desktop\Py Projects\link_objects\class_2.cpp|13|warning: unused variable 'y' [-Wunused-variable]| C:\Users\Geoff\Desktop\Py Projects\link_objects\main.cpp|3|warning: extra tokens at end of #include directive| C:\Users\Geoff\Desktop\Py Projects\link_objects\main.cpp|4|warning: extra tokens at end of #include directive| C:\Users\Geoff\Desktop\Py Projects\link_objects\class_1.h|7|error: redefinition of 'class Class1'| C:\Users\Geoff\Desktop\Py Projects\link_objects\class_1.h|7|note: previous definition of 'class Class1'| ||=== Build failed: 2 error(s), 3 warning(s) (0 minute(s), 0 second(s)) ===|

I am very new to C++ and I'm pretty sure I'm going about this all wrong... I think what I'm doing would work if i was trying to store say a struct inside another struct maybe, but i don't understand what I'm doing wrong exactly any help appreciated thanks

EDIT

Thanks for your help, I seem to have it working now by adding header guards and setting the stored_class attribute inside the Class2 constructor. I also wanted to pass by ref so i could change class1 from within class2. the code looks like this:

main.cpp

#include <iostream>

#include "class_1.h";
#include "class_2.h";

using namespace std;

int main()
{
    cout << "Creating class 1..." << endl;

    // create class1, seems to work fine
    Class1 class1(5);

    cout << "Passing class 1 to class 2..." << endl;

    // i want to create class2, and pass the class1 instance of Class1
    // so it can be stored and accessed by Class2
    Class2 class2(class1);

    cout << "Class 1 this_x from Class 2=" << class2.stored_class.this_x << endl;

    class1.this_x = 4;

    cout << "Class 1 this_x from Class 2=" << class2.stored_class.this_x << endl;

    return 0;
}

class_1.h

#ifndef CLASS_1_H_INCLUDED
#define CLASS_1_H_INCLUDED

class Class1
{
    private:


    public:

        // some variable we can store and access
        int this_x;

        // constructor
        Class1(int x);

};

#endif // CLASS_1_H_INCLUDED

class_1.cpp

#include "class_1.h"

// in the constructor set value of this_x to x
Class1::Class1(int x)
{
    this_x = x;
}

class_2.h

#ifndef CLASS_2_H_INCLUDED
#define CLASS_2_H_INCLUDED

#include "class_1.h"

class Class2
{
    private:

    public:

        // constructor, will receive a Class1 object instance
        Class2(Class1 &store_class_1);

        // declare the variable that I want to store Class1 in
        Class1 &stored_class;

};

#endif // CLASS_2_H_INCLUDED

class_2.cpp

#include "class_2.h"

// constructor for Class2, takes a Class1 object
Class2::Class2(Class1 &storeClass1): stored_class(storeClass1) {}

QUESTION:

According to the example here https://www.w3schools.com/cpp/cpp_constructors.asp they use a different style of code to set the member variables. How come when I try this inside class_2.cpp I'm getting an error? I would think this format would be metter so I could do more within the Class2 constructor?

Class2::Class2(Class1 &storeClass1) {
    stored_class = storeClass1;
}
Geoff L
  • 765
  • 5
  • 22
  • 1) Add [include guards](https://en.wikipedia.org/wiki/Include_guard) to your headers. 2) Initialize members in constructor initializer list, as in `Class2::Class2(Class1 storeClass1) : stored_class(storeClass1) {...}` – Igor Tandetnik Aug 08 '20 at 23:09

1 Answers1

0
    // declare the variable that I want to store Class1 in
    Class1 stored_class;

You have a class member called stored_class1. Now, let's take a look at your constructor:

Class2::Class2(Class1 storeClass1)
{

This constructor fails to initialize the stored_class member. It does have a Class1 parameter. That's great, but just because a constructor has a parameter doesn't mean that the constructor will initialize a class member of the same type, automatically. You are responsible for doing this, yourself:

Class2::Class2(Class1 storeClass1)
       : stored_class{storeClass1}
{
Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • thanks for your help! I made the suggested changes and it seems to work now, tho i just have 1 more question please see the bottom of the edit i made. I don't understand why I can't set the class attribute that way, and also why is setting the class attribute required at all within the constructor? In this example here https://www.w3schools.com/cpp/cpp_classes.asp#:~:text=Previous%20Next%20%E2%9D%AF-,C%2B%2B%20Classes%2FObjects,such%20as%20drive%20and%20brake. they don't set it until after instantiating the object. thanks again – Geoff L Aug 08 '20 at 23:38
  • @GeoffL because thats a variable, and not a field initialization. – user1937198 Aug 08 '20 at 23:44
  • I think also because I'm passing by ref? Thanks – Geoff L Aug 08 '20 at 23:46
  • No, passing by reference has nothing to do with it, whatsoever. The constructor is responsible for initializing a class member. If the constructor does not initialize a class member it must have a default constructor. `Class1` does not a default constructor, so it must be initialized, in the constructor's initialization section. Assigning something to a class member, in the constructor, is not the same thing as initializing it. The class used in that example has a default constructor. The End. – Sam Varshavchik Aug 08 '20 at 23:51