-4

This question led me on a wild goose chase, so I wanted to revise it to get the facts straight.

I am working with a set of classes which were arranged like this

//third party .h file
class ChildX : public ParentY {
  public:
    OtherClass member;
}

//third party .h file
class ParentY {
  protected:
     ParentY();
  //other public attributes
}

//third party .cpp file
ParentY::ParentY {       
}

Any time I tried to compile one of these classes I got an unhelpful error message

Undefined reference to 'ParentY::ParentY()' in function 'SomeClass::DoX()';

The error is completely unhelpful, but I have finally determined that the problem is caused by the constructor in the CPP file. Apparently the code which includes the ChildX.h file does not link with the constructor hidden in the ParentY.cpp file. The solution (e.g. https://ubuntuforums.org/showthread.php?t=1966081) seems to require that the cpp file in question be compiled before running the rest of the build.

So now that I have figured out WHAT the error is and how to resolve it, I just need to figure out how to do it in QtCreator

BSD
  • 329
  • 3
  • 13
  • 5
    `CoreStruct x;` and `new CoreStruct();` use the same constructors. – François Andrieux Nov 09 '17 at 18:16
  • 1
    `Some of the classes have no defined constructor.` then `CoreStruct x;` won't work either. – Yakk - Adam Nevraumont Nov 09 '17 at 18:18
  • 1
    Wait a second. Please clarify: They have no constructor or they have no default (parameterless) constructor but do have a constructor that requires parameters? – user4581301 Nov 09 '17 at 18:19
  • 2
    If a class has a non-default constructor, the default constructor is not automatically generated and you cannot instantiate the class without providing the requested parameters. More here: http://en.cppreference.com/w/cpp/language/initializer_list I recommend skipping down to the explanation section because the section on syntax will probably read like Martian if you try and read it first. – user4581301 Nov 09 '17 at 18:28
  • This method not calling constructor: `CoreStruct * p3 = (CoreStruct*) ::operator new (sizeof(CoreStruct));` But this very bad way for create objects of class. – svm Nov 09 '17 at 18:33
  • @svm beyond bad. Very likely fatal. If a constructor needs parameters, odds are very good that the object will misbehave if they are not properly set. – user4581301 Nov 09 '17 at 18:37
  • @FrançoisAndrieux Okay, but I am more confused by this. If the protected constructor in the parent class is being called in either case, then why does only the latter form create an error? I would expect that both would have the same results and they are plainly not. – BSD Nov 09 '17 at 20:35
  • @FrançoisAndrieux I did some checking and found that I apparently can't construct ChildX using either method. The other error was masking this finding. Thanks for tipping me to this. – BSD Nov 09 '17 at 21:20
  • @BSD If the constructors are protected, it's a sign that the class must be derived. You should then be able to instantiate the derived type. – François Andrieux Nov 10 '17 at 14:09

1 Answers1

0

The solution comes in three parts.

  1. Separately compile the cpp file into a .o object. I'm not going to talk about this step as I was able to use pre-compiled .o files for the third party library I was using. Apparently they were aware of the issue as well and prepared .o files for all their classes.

  2. Following the advice of How to add object files to a project in Qt add the .o files to the LIBS portion of Qt's .pro file.

  3. You may have additional dependencies between the .o file you compiled and other .o objects. If you can get all of them in one place you can get all the dependencies at once with a single line in the .pro file.

    LIBS += /path/to/object/files

BSD
  • 329
  • 3
  • 13