简体   繁体   中英

Going from Java to C++: how to use one custom class var within another custom class?

Let's say I have two custom classes in Java, class A and class B:

class A {
    int x;
    int y;
    public A(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}

class B {
    A a;
    int z;
    public B(A a, int z) 
    {
        this.a = a;
        this.z = z;
    }
}

And I want to translate this situation into C++.

class A will translate more or less as it is, but when I go to class B and write such code:

class B {
    A a;
    int z;
    public:
    B(A a1, int z1){
        a = a1;
        z =z1;
    }  
};

it complains saying that class A does not have default constructor, so when I declare A a; at the top of class B it cannot instantiate my "a" variable (Java does not instantiate at declaration, whereas C++ does, as I understand).

So what would be the normal C++ way to deal with this situation: should I add default constructor without arguments to class A, or this is not the right way to go?

Thanks a lot.

Translating from Java to C++ is very sensitive to context. They are really very different languages and it depends heavily on what you are trying to achieve.

In Java user defined types are all accessed via references. The functional equivalent in C++ is a pointer. However in C++ you can access objects directly like built in types. So you could write this:

class A {
    int x;
    int y;

public:
    // note: we don't initialize members in the body
    A(int x, int y): x(x), y(y) {}
};

class B {
    A a;
    int z;

public:
    B(A a, int z): a(a), z(z) {}
};

C++ gives you many more options how to refer to your user defined types and so it really depends on the larger problem you need to solve.

Some other possibilities:

std::shared_ptr<A> a; // much more Java-like (slower)
std::unique_ptr<A> a; // when you need one copy only (more common)
A* a; // when you need to live dangerously
A a; // use it more like a built-in

References:

std::unique_ptr when you only need to manage one

std::shared_ptr when the object needs to be managed from multiple places

NOTE: The difference between how you use Java and how you use C++ are so large that I would recommend forgetting about Java while you are dealing with C++ . Learn C++ independently as a new language without constantly referring to the "Java way" of doing things.

Recommended books: The Definitive C++ Book Guide and List

in class B initialise instance of class A in initialisation list like so B(A a1, int z1):a(a1) {...} This is required as instance of class A inside class B will be initialised before executing constructor body with default constructor, You have defined Your own constructor for A so there is no default constructor anymore. You can also initialise z1 variable the same way, like this: B(A a1, int z1):a(a1),z(z1){...}

In Java, a declaration like:

A a;

means that you want a reference that can point to an object of type A. You eventually set it with something like:

a = new A(x, y, z);

In C++ the nearest simple thing is a pointer:

A* a;

When you write:

A a;

in C++, you are asking the compiler to make a local object, right here. So you have to supply all the constructor args. That's not what your Java code is doing, so you don't want it in C++ if what you are doing is a line-by-line, straight, port. (Hint: you would be better off writing yourself an explanation of what the program does and then creating a Java implementation in idiomatic Java from scratch.)

If you are trying to map from Java to C++, which is a very dangerous process, every declaration like:

A a;

has to map to either:

A* a;

or

A& a ... /* some initialization, unless a parameter or member. */

and you have to worry about all the storage allocation for yourself.

a = a1; is not an initialization of a . It's an assignment . a was already initialized before that statement (or would've been if it had a default constructor, hence the error).

In C++, each member variable is initialized before entering the constructor body. You have to use the member initialization list if you want to initialize a with a1 :

B(A a1, int z1) : a(a1), z(z1) { /* constructor body */ }

This will simply initialize a with a1 and z with z1 , and is the way to do it in C++.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM