Hello,
I have some java code I want to port to C++, and first class in the Heirarchy has me stumped. I'm trying to port a simple parsing framework as an exercise to figure out how it works internally, and almost everything in the framework requires, uses, or is PubliclyClonable a class defined in java as:

public abstract class PubliclyCloneable{
    public abstract Object clone();
}

As C++ has no Object class I wanted to define the C++ version like this:

class Cloneable{
    virtual Cloneable clone()=0;
}

Visual Studio Intellisense says this isn't allowed, and I don't have a .cpp to actaully attempt to compile yet. that is the only code in my project so far. Is the proper way to do this to make a pure virtual operator=? what would be the best way to define this high level class in the heirarchy that would ensure an always deep copy of a class?

For those curious about the framework I'm trying to port it is from the book Building Parsers with Java and the source code is on its website.

Moving from Java to C++, the main thing to understand well is the distinction between Java's reference-semantics and C++'s value-semantics. Simply put, everything in Java is a reference (or placeholder, or pointer) for an object (managed by the garbage collector). In C++, everything is a value (or object, or variable) (e.g., int), which could be an address-value (pointer) (e.g., int*) or a alias for a value (reference) (e.g., int&).

Now, to the problem in your code:

class Cloneable {
  public:  // (I added 'public:', otherwise your clone() function is private).
    virtual Cloneable clone()=0;
}

There are two things to notice. First, the presence of a pure virtual function makes the class abstract, which means, in C++, that it cannot be instantiated (i.e., you cannot create an object of that class). Second, the member function clone() returns an object of type Cloneable, that is, not a reference, not a placeholder nor a pointer, but an actual object (by value). Do you see a contradiction? Such an object cannot be created because Cloneable is abstract.

Basically, to do what you want to do you have to return things by pointer:

class Cloneable{
  public:
    virtual Cloneable* clone() = 0;  // notice Cloneable* (pointer)
}

However, using a raw pointer is not really recommended for a factory function (or clone function). It is preferrable to use a smart-pointer such as std::shared_ptr or std::unique_ptr. And because std::unique_ptr is moveable into a std::shared_ptr, that is the preferred smart-pointer to use, as so:

class Cloneable{
  public:
    virtual std::unique_ptr<Cloneable> clone() = 0;
}

Thanks for the reply, I forgot the "public" when I was typing the question. I thought I was forgetting something simple about the C++/Java differences and it was pointers. Rookie mistake, now I feel silly. Turns out I'm more out of practice in C++ than I thought. I'll look up the smart-pointers, because I haven't used them before.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.