1

Please excuse me but I didn't know to give a name to the title in a short way.

Why do I need to declare an overloaded operator inside the header to make it work in this example:

HEAD.H

#pragma once

namespace test {
    class A {
    public:
        A() : x(0) {}
        int x;
    };
    A& operator++(A& obj);  //this is my question
}

HEAD.CPP

#include "head.h"

namespace test {
    A& operator++(A& obj) {
        ++obj.x;
        return obj;
    }
}

MAIN.CPP

#include <iostream>
#include "head.h"
using namespace std;
using namespace test;

int main() {
    A object;
    ++object;  //this won't work if we delete declaration in a header
    return 0;
}

operator++ is defined and declared in a namespace inside "head.cpp" so why do I need to declare it one more time in a header? Thank you.

codekiddy
  • 5,897
  • 9
  • 50
  • 80
  • Why do you not declare the operator in your class?? – AlexTheo Nov 18 '11 at 22:04
  • @Alex : Defining non-assignment operators outside of your class is generally considered good practice. However, the operator could be defined `inline` inside of the header... – ildjarn Nov 18 '11 at 22:11
  • @Alex I defined it outside of a class cos of this example on which I'm strugling currently, it could be the same question on any other function. thanks. – codekiddy Nov 18 '11 at 22:16
  • Just found a good answer here: http://stackoverflow.com/questions/4652932/why-define-operator-or-outside-a-class-and-how-to-do-it-properly :) – AlexTheo Nov 18 '11 at 22:22

1 Answers1

5

The CPP files are compiled independently of each other, and they only see the header files they've included (which are in fact textually added to the source code of the CPP before compilation). As such you'll use the header file to inform the compiler that a function exists with that signature (be it an operator overload).

Then the output from your CPP files is put together by the linker, which is when you'd find out if for instance you had declared a function in a header file but never taken the trouble to implement it.

Simple example with namespaces:

#include <iostream>

namespace test{
    int f() { return 42; }
    int g() { return -1; }
}

namespace other{
    int f() { return 1024; }
}

using namespace other;

int main(){

    //error: 'g' was not declared in this scope
    //std::cout << g() << std::endl;

    std::cout << test::f() << std::endl; //42
    std::cout << f() << std::endl; //1024

    return 0;
}
Vlad
  • 18,195
  • 4
  • 41
  • 71
  • Yeah, during compilation head.cpp has no effect on main.cpp, they just don't see each other. For example, try removing the operator in head.cpp but leaving your declaration in head.h. main.cpp will still compile just fine. (there will be an error in the linking stage after compilation.) This is a result of the C++ compilation model. – bames53 Nov 18 '11 at 22:08
  • I know I sound noobish but I just dont get the point, I've included everything from namespace in my "MAIN.CPP" by "using namespace test" so operator function is defined and visible and why it doesnt work then? header is just a declaration. – codekiddy Nov 18 '11 at 22:10
  • Sadly that's not how C++ namespaces work. See [here](http://www.glenmccl.com/ns_comp.htm) for a quick introduction. Essentially they're about grouping things logically and eliminating naming conflicts. Among other things, `using namespace std` allows you to say `cout << ...` instead of `std::cout << ...`, but it doesn't mean you don't have to include ``. – Vlad Nov 18 '11 at 22:16
  • When you are compiling main.cpp the compiler will NOT see what is inside head.cpp. "using namespace test" will not pull in any stuff declared in head.cpp, it will just take the namespace test and make every symbol, that is in namespace test, also available without explicitly preceedig it with the namespace; after "using namespace test" you do not need to write test::A, you can just write A. – Werner Henze Nov 18 '11 at 22:20
  • OK!! I got it now, I thought namespaces have similar behaviour as headers.(sily me) thanks a bunch to everyone. – codekiddy Nov 18 '11 at 22:33