1

In C++, I am trying to put two classes in separate files into the same namespace.

I get two errors in main saying that the class Head is not in the namespace Names, and that days is not declared in this scope.

It seems that when I switch the order of the #include statements, the class that doesn't work flip flops between the two. From what I've read, the namespace should open again when the second file is included, and put the second class into the namespace, but it isn't working.

Why does the order of which one I include matter as to which works? What can I do to make both classes be a part of the same namespace, while keeping them in separate header files?

main.cpp

#include <iostream>
#include "dy.hpp"
#include "dayyear.hpp"

int main(){
   int d=2;
   int y=5;
   Names::Dy yup(y,d);
   Names::Head days(y,d);
   days.print();
   yup.print();
   return 0;  
}

dayyear.hpp

#ifndef DY_H
#define DY_H

namespace Names{
   class Head{
      int year;
      int day;
   public:
      Head();
      Head(int y, int d);
      void print();
      void change(int y, int d);
   };
}
#endif

dayyear.cpp

#include <iostream>
#include "dayyear.hpp"

Names::Head::Head(){
   day=0;
   year=0;  
}

Names::Head::Head(int y, int d){
   day=d;
   year=y;  
}

void Names::Head::print(){
   std::cout<<day<<", "<<year<<std::endl;
}

void Names::Head::change(int y, int d){
   year=y;
   day=d;  
}

dy.hpp

#ifndef DY_H
#define DY_H

namespace Names{
   class Dy{
      int year;
      int day;
   public:
      Dy();
      Dy(int y, int d);
      void print();
      void change(int y, int d);
   };
}
#endif

dy.cpp

#include <iostream>
#include "dy.hpp"

Names::Dy::Dy(){
   day=0;
   year=0;  
}

Names::Dy::Dy(int y, int d){
   day=d;
   year=y;  
}

void Names::Dy::print(){
   std::cout<<day<<", "<<year<<std::endl;
}

void Names::Dy::change(int y, int d){
   year=y;
   day=d;  
}
Remy Lebeau
  • 454,445
  • 28
  • 366
  • 620
Frajaro
  • 23
  • 2
  • 7
    You use the guard `DY_H` in two different files. Including one of those files will prevent the other from being included. – François Andrieux Feb 21 '18 at 19:18
  • You can change `dy.hpp`'s guard to `DY_HPP` – Patrick Roberts Feb 21 '18 at 19:20
  • 2
    This is why I use `#pragma once`; I've been bit by forgetting to change header guards more than once, and all the compilers I care about support it – Justin Feb 21 '18 at 19:20
  • 1
    If you want to use a `#define` guard, then you should consider a naming like `___H_`. – t.niese Feb 21 '18 at 19:21
  • 1
    @Justin: not all C++ compilers support `#pragma once`, though – Remy Lebeau Feb 21 '18 at 19:22
  • 1
    @Justin [Not everyone agrees with using `#pragma once`](https://stackoverflow.com/questions/1143936/pragma-once-vs-include-guards/34884735#34884735) – François Andrieux Feb 21 '18 at 19:24
  • @FrançoisAndrieux I never said that everyone agrees. I'm merely remarking that the OP could consider using it. It's not fit for every purpose / company, but it's a decision that has to be made (whether to use `#pragma once` or header guards) – Justin Feb 21 '18 at 19:25
  • @Justin I guess I misread your comment. I had the impression that it was advocating that `#pragma once` was the superior solution, but on a second read it seems reasonable. – François Andrieux Feb 21 '18 at 19:27
  • @FrançoisAndrieux Sorry about that; on a second read I could see that the comment might seem like I was advocating. *Natural language* is so ambiguous – Justin Feb 21 '18 at 19:27
  • @Justin I think better solution is to have proper IDE or editor that generates guards properly – Slava Feb 21 '18 at 19:29
  • @Slava It's a good solution, but I still forget because I copy-paste a header to create a new header that's similar, but forget to change the guard. If I worked at a company that required me to use header guards, though, that's absolutely what I'd do, and just suck it up and deal with it. – Justin Feb 21 '18 at 19:30

1 Answers1

1

That is because both dayyear.hpp and dy.hpp have:

#ifndef DY_H
#define DY_H
.....
#endif

dayyear.hpp should have:

#ifndef DAYYEAR_H
#define DAYYEAR_H
.....
#endif

The preprocessor only regards the first appearance of the same #infdef/#define/#endif construct, all the subsequent ones are replaced with empty code. That is why the order of #include statements matters.

nVxx
  • 601
  • 7
  • 18