XAnguera
XAnguera

Reputation: 1267

public header class constructor

I am new at building distributable libraries written in C++ and I am getting a bit lost. I have created a .cpp file with wrappers for all functions I want the library to offer users, and I have written 2 .h files, one public and one private. Below is a dummy example of my header files:

public.h:

class myclass
{
public:
    public_function();
private:
}

private.h:

class myclass
{
public:
    public_function();
private:
    anotherClass instanceofClass;
}

Note that the implementation of public_function() uses the "instanceofClass" in the code. I have been able to compile with no problem the code using the private class and to compile and link the library with external programs using the public header and the compiled library. When executing that code, though, I am getting segmentation faults that I suspect have to do with lack of proper initialization of "instanceofClass".

Am I doing the right thing? Am I forced to instantiate "instanceofClass" inside the implementation of public_function() for it to be initialized properly, or is there anything else I should do instead?

Thanks a lot.

Upvotes: 3

Views: 159

Answers (4)

didierc
didierc

Reputation: 14730

Your class lacks a proper constructor, which means that the compiler will provide a default one based on the content of the class definition. If that definition isn't consistent accross all the code, it won't get initialized the same way everywhere, and some data may be missing.

If you want to hide the implementation details of instanceofClass, just do a forward declaration in the header (the private header you're providing is correct, you can use it as your public one), and provide an implementation somewhere in your code.

Upvotes: 1

combinatorial
combinatorial

Reputation: 9561

You can't declare the same class 'myclass' in two different ways. There has to be a single class definition. If you want to hide the implementation's API you want to use the 'Pimpl' idiom. So your public class has a single pointer to a private class. For example:

public.h

class myclass_private;
class myclass {
    private:
        myclass_private* pimpl; 
    public:
        myclass();
        void public_function();
};

public.cpp

myclass::myclass() {
    pimpl = new myclass_private;
}

void myclass::public_function() {
     pimpl->private_function();
}

private.h

class myclass_private {
    public:
        void private_function(); 
};

Upvotes: 6

Dietmar Kühl
Dietmar Kühl

Reputation: 153840

The definition of a class shall not changr between different translation units. This is one of the aspects of the One Definition Rule. What you might want to donis to define the publicly visible class to have a pointer to a private implementation: the Pimpl Idiom:

class Public {
public:
    ...
private:
     struct Impl;
     Impl* impl_;
};

The struct Impl would only be defined in the implementation file.

Upvotes: 1

01d55
01d55

Reputation: 1912

The myclass defined in public.h has no members, and is therefore sized 1 byte. The myclass defined in private.h encapsulates anotherClass, and is therefore whatever size anotherClass is. This inconsistency is the root of your problem.

What you ought to do is have only one header, and use a pointer (which doesn't require a class definition) to enable hiding the implementation of anotherClass. I'll repeat Joachim's link to the pimpl idiom for elaboration.

Upvotes: 1

Related Questions