-6

Most classes appear to be separated between declaration and definition in the following form using namespace qualifier to define the class:

// test.h

class test 
{
    public:
        void func1(void);

    private:
        void func2(void);
};

// test.cpp

void test::func1(void)
{
    //whatever
}

void test::func2(void)
{
    //whatever
}

Why don't we typically see people use the keyword class in the .cpp file? Like in the following form:

// test.cpp

class test {

    void func1(void)
    {
        //whatever
    }

    void func2(void)
    {
        //whatever
    }

};

Is it just convention to use the namespace qualifiers? Or because it make more sense when you starting implementing a class via multiple source files?

Izzo
  • 4,461
  • 13
  • 45
  • 82
  • Is your question "why are class definitions normally in header files rather than source files?"? – Oliver Charlesworth Aug 26 '16 at 16:47
  • related/dupe: http://stackoverflow.com/questions/333889/why-have-header-files-and-cpp-files-in-c – NathanOliver Aug 26 '16 at 16:48
  • @OliverCharlesworth No, my question is why do you use namespaces to resolve class definition scope as opposed to just using the keyword 'class' in the actual cpp file. – Izzo Aug 26 '16 at 16:50
  • _"Why don't we typically see people use the keyword class in the .cpp file? "_ You will see that if you look a code using [the PIMPL idiom](https://msdn.microsoft.com/en-us/library/hh438477.aspx). – Michael Aug 26 '16 at 16:50
  • @NathanOliver No I understand why we separate declaration and implementation, but I'm curious as to why we use namespaces to resolve scope instead of just using the keyword 'class' – Izzo Aug 26 '16 at 16:50
  • So you want know why we use a namespace to group functions instead of a class with a bunch of static functions? – NathanOliver Aug 26 '16 at 16:51
  • 4
    @Teague please stop using namespace to describe that. It's generating additional confusion--namespaces are used to refer to namespaces, and not classes, even when the class name appear to be used like namespaces usually are. The term you're looking for is "qualified name" – jaggedSpire Aug 26 '16 at 16:51
  • @NathanOliver Yes. – Izzo Aug 26 '16 at 16:52
  • Well think about it. `class` makes a object. It is kinda pointless to make a object that actually isn't a object but just a group of related functions. Nothing stops you but IMHO it is not a correct usage of a `class`. – NathanOliver Aug 26 '16 at 16:54
  • 2
    @Teague So the question is, "When defining functions declared in a class in a .h file, in a .cpp file, why do we not do the same thing namespaces do and reopen the enclosing scope where we declared the functions, instead of referring to the functions by their qualified name when we define them?" – jaggedSpire Aug 26 '16 at 16:54
  • or, in layman's terms: When we declare functions in a namespace like `namespace ns{void foo();}` we define them like `namespace ns{void foo(){}}`. Why don't we do the same things with classes? – jaggedSpire Aug 26 '16 at 16:59
  • Without the previous class definition, that would still be valid and define a class with two private functions, which isn't what anybody wants. – molbdnilo Aug 26 '16 at 17:02
  • @molbdnilo I could see the names in the class definitions getting merged if there's more than one of the same name in a single translation unit, with errors for inconsistent accessibility but otherwise matching signatures. Of course, that would increase complexity because of introduction of merging rules, cause issues with additional members inflating the size of the class in only *some* translation units, and other such fun adventures in the land of complexity. – jaggedSpire Aug 26 '16 at 17:22
  • @Teague could you please confirm or deny my interpretation of your question? – jaggedSpire Aug 26 '16 at 17:23
  • 1
    @Teague I mean for one thing, I'm fairly certain your code wouldn't compile with most compilers. Assuming you're `#include`-ing the header file, I get `error: redefinition of 'class test'`. Are you asking about why it's not allowed? – Keith M Aug 26 '16 at 17:32

1 Answers1

1

Let's view this question from another angle...

It is possible to use the same syntax for both, but it's "the other one"; the following is perfectly valid:

namespace ns
{
    int foo();   
}

int ns::foo() { return 0; }

Looked at like this, it's the opposite question that's interesting, "why is it common to include the word 'namespace' in .cpp files?"

There's one substantial difference between namespaces and classes that makes namespace {} necessary in so many places: namespaces are open to extension, but classes are defined entirely by their (one and only) definition.

Like with classes, you can't add anything to a namespace using the syntax above; you can't add a function bar above with only int ns::bar() { return 9; }, the only way to add names to a namespace is "from within".

And, as many have discovered, it's convenient to wrap an entire file in a namespace and not use the qualified names, even if you're not adding any names to it.

Hence the popularity of "namespace": it's a convenience enabled by the extensibility of namespaces.

Another issue is that the meaning of your "test.cpp" would depend on whether the class definition has already been seen by the compiler – without it, that's a valid and complete definition of a class with two private functions.
This kind of "action from a distance" depending on possibly very distant code is painful to work with.
It's also worth noting that namespaces were added some twenty years after "C with classes" was created, when C++ was a well established language, and changing the meaning of a construct that literally hasn't changed in decades is pretty much unthinkable.
Partularly if all it does is save a few keystrokes.

molbdnilo
  • 64,751
  • 3
  • 43
  • 82