1

In Java:

private State current_state;

As "State" is a superclass, I can then assign subclass objects to current_state, effectively making current_state point to a different object:

current_state = low_state;

What is the equivalent of doing this in C++. My understanding is that references can't point to different objects once declared.

Would the above syntax work? If so, would it work in the same way as it does in Java? Even then, is this good practice in C++?

3

If you're talking about variables of user-defined polymorphic types, then in C++ you need to use a pointer or a reference in order to achieve runtime polymorphism. The exact syntax you're describing is probably legal in C++ (hard to say since you didn't give a complete example), but results in "object slicing" rather than polymorphism.

The reason is that a non-pointer/non-reference variable in C++ always indicates an object that is stored on the stack and has a known-at-compile-time structure (though that known structure may include pointers to unknown stuff). The only way to compile code using objects with unknown structure is to use pointers or references to those objects, since the structure of a pointer or reference is the same and known at compile time no matter what it points to. This is why runtime polymorphism always has to be implemented with some kind of pointer, whether or not your language chooses to expose those pointers to you. Unlike Java, C++ does expose them.

Also, references can be assigned to more than once. What you can't do is create an uninitialized reference, i.e. pointers can be null but references cannot.

Exactly what syntax you use depends on whether you want references or raw pointers or smart pointers, which is something you need to understand in C++ but not in garbage-collected languages in Java (seriously, it's not optional, go read Effective C++ and/or Effective Modern C++ for a crash course on this and other need-to-know material). But here's a trivial example to get you started:

#include <iostream>
#include <memory>
using namespace std;

class Base {
public:
    virtual int foo() {
        return 1;
    };
};

class Derived : public Base {
public:
    int foo() {
        return 2;
    };
};

int main() {
    Base b;
    cout << b.foo() << endl; // prints 1
    Derived d;
    cout << d.foo() << endl; // prints 2

    b = d;
    cout << b.foo() << endl; // prints 1
    // Because b is not a pointer, the Derived object
    // gets "sliced" by the assignment.

    Base& br = b;
    cout << br.foo() << endl; // prints 1

    Base& dr = d;
    cout << dr.foo() << endl; // prints 2 because polymorphism

    unique_ptr<Base> up1 = make_unique<Base>();
    cout << up1->foo() << endl; // prints 1

    unique_ptr<Base> up2 = make_unique<Derived>();
    cout << up2->foo() << endl; // prints 2 because polymorphism

    return 0;
}
1

If you need to be able to assign a subclass instance to a variable in c++, and you need reassignment, then what you want is a pointer.

private: State* current_state;

If there's ownership involved, you should use a smart pointer like unique_ptr or shared_ptr.

shared_ptr most closely matches the semantics of Java references, other than the fact that it cannot deal with reference cycles

0

Your doing what is called 'downcasting'. You can do this in C++, however, it's not recommended (imho) because of the various baggage that C++ has that Java doesn't.

  1. Direct downcasting (like the example above) will 'slice' off derived data when cast to the base class. To avoid this, you need to use pointers.

  2. RTTI. This is a feature where you can determine the type of a downcast object using std::typeid and cast something using dynamic_cast<>. However, many people turn this feature off during compiling.

My general rule of thumb is that if you are downcasting, you should rethink what your doing. There are a number of ways to solve a problem without the need to manipulate base classes directly (virtual functions and double dispatch).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.