1

I have a noob question here. I'm getting my head around the C++ structure and syntax and I've hit a bit of a wall. I know I am missing something from my concept. So first a little code to help describe the situation.

Control.h

#pragma once
#ifndef CONTROL_H
#define CONTROL_H

class Control
{
    public:
        Control();
        ~Control();
    private:
    public:
};

#endif /*CONTROL_H*/

Control.cpp

#include "Control.h"
#include "Hello.h"

Hello helloObj;

Control::Control()
{
}

Control::~Control()
{
}

int main()
{
    int a = helloObj.HelloWorld();
    return 0;
}

Hello.h

#pragma once
#ifndef HELLO_H
#define HELLO_H

class Hello
{
    public:
        Hello();
        ~Hello();
    private:
    public:
         int HelloWorld(void);
};
#endif /*HELLO_H*/

Hello.cpp

#include "Hello.h"

Hello::Hello()
{
}

Hello::~Hello()
{
}

int HelloWorld()
{
    return 5;
}

I try and compile control.cpp with g++ on OSX 10.7 and get

Undefined symbols for architecture x86_64:
      "Hello::Hello()", referenced from:
              __static_initialization_and_destruction_0(int, int)in cccZHWtd.o
      "Hello::~Hello()", referenced from:
              ___tcf_1 in cccZHWtd.o
      "Hello::HelloWorld()", referenced from:
              _main in cccZHWtd.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

Is it the compiler, my code or my concept of whats going on? Am I not instantiating something correctly?

Any links describing this in more detail would be appreciated.

Ultimately I want to be able to run a function in another class and return the result...normal OO, keeping your program modular stuff....

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
JasonDC
  • 71
  • 5
  • It should be `int Hello::HelloWorld()` in `Hello.cpp`, but other than that - are you sure `Hello.cpp` is included in your build? What are you passing to the compiler? – James M Feb 17 '12 at 02:41

3 Answers3

1

The errors you are getting are Linking errors not compilation errors.
The linker is not able to find definitions of the said functions & hence it reports the errors. It seems You have not included the Hello.cpp file containing the function definitions in your project.

Make sure Hello.cpp is included in your project and is a part of your project or
If you are using command line for compilation and linking make sure you have specified Hello.cpp in the file names on the command line.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
0

Most of the issue is me not being familiar as I should be with g++ (Thanks Als). There were are few syntax issues as well (Thanks Brain).

Here is the corrected (albiet slightly bloated for an overview of stucture) code and g++ command

Control.h

#pragma once
#ifndef CONTROL_H
#define CONTROL_H

class CONTROL
{
    private:
       //nothing defined yet...
    public:
        Control(); //default constructor
        ~Control(); //default destructor
};
#endif /*CONTROL_H*/

Control.cpp

#include "Hello.h"
#include "Control.h"

Hello helloTest; //instantiates the Hello Object

Control::Control()
{
}

Control::~Control()
{
}

int main()
{
    helloTest.HelloWorld();
    return 0;
}

Hello.h

#pragma once
#ifndef HELLO_H
#define HELLO_H

class Hello
{
    private:
        //nothing defined yet
    public:
        Hello(); //default constructor
        ~Hello(); //default destructor

        void HelloWorld();
};
#endif /*HELLO_H*/

Hello.cpp

#include "Hello.h"
#include <iostream> //so we can use 'cout'

using namespace std;

Hello::Hello()
{
}

Hello::~Hello()
{
}

void Hello::HelloWorld()
{
    std::cout << "Hello lovelies!\n"; //The magic word.
}

Then we run g++ like so

g++ -o Hello ./Control.cpp ./Hello.cpp

g++ [option] [output file name] [input files]

JasonDC
  • 71
  • 5
-1

First of all:

    public:
    Hello();
    ~Hello();
    private:
    public:

is pointless, a class defaults to private, and there is no need to make it public twice nor do I know if you can do that furthermore if you have no private members private should not be in there (not trying to be mean just some advice :-) )

Now to answer the question (with a guess DISCLAIMER: I AM NOT 100% FAMILIAR WITH GCC):

This is a linker error, it may be there because the compiler can not find the definition of HelloWorld(void);. Let me explain:

In your header file you wrote:

int HelloWorld(void);

However in your .cpp you write:

int HelloWorld()
{
   return 5;
}

The function's (or in this case method because it is inside a class) arguments need to be exactly the same in the header and source, you can not even change the names (or at least you cant with VC++ which is what I use; I have little experience with gcc) so this may be resolvable by typing

int HelloWorld(void)
{
   return 5;
}

Next (DISCLAIMER I AM NOT 100% familiar with the pre-proccsor):

You also use the #pragma once pre-proccsor tag, I dont use it but I believe that means you can only include a file once and you have included Hello.h and Control.h twice, like I said I am no expert in the pre-proccsor but you commented out

HELLO_H

and

CONTROL_H

  • Yes, you can have as many uses of "public:" in your class as you like; in C++ (unlike C) a function signature with no arguments is the same as one that explicitly says "void"; and #pragma once means that if a file is included more than once in the same translation unit (which incidentally, doesn't happen in this example), it only gets processed once, it's not an error to do that. – Dan Hulme Feb 17 '12 at 20:42
  • @DanHulme Yes it is the same to say () and (void) do the same thing, however I was suggesting the linker may think that they were two totally different things because they were not the same, this is the way it is in VC++. – The Floating Brain Feb 18 '12 at 00:44