-3

I'm working on a new application, based on templates, STL, namespaces, ... (my collegues have taken all necessary steps to make a mess), now I just want to add a property to a class, and this does not work, let me show you):

Within a header-file:

namespace utils{

class Logging_Manager : public Singleton<Logging_Manager> {
    friend Singleton<Logging_Manager>;

    Logging_Manager();

private:
    std::vector<std::shared_ptr<Single_Logger>> logging_modules;
    LogLevelType loglevel; // 0 : no logging, 1 : info logging, (2-4 are not used), 5 : debug, 6 : everything
public:
    Timer getDebuggerTimer;
    Timer getFileTimer;

I've just added the last entries getDebuggerTimer and getFileTimer myself and this does not compile, due to the compiler errors C3646 and C4430.

All I mean is that both are properties of the type Timer, I don't mean those things to be templates of some methods which might be abstract, virtual, or whatsoever, no they are just to meant as properties, nothing more nothing less.

As I didn't find a way to add both timers to my header file, my boss has just solved the issue as follows:

class Timer;    // this class is defined elsewhere, how can it be put here and make things work?
namespace utils{

class Logging_Manager : public Singleton<Logging_Manager> {
    friend Singleton<Logging_Manager>;

    Logging_Manager();

private:
    std::shared_ptr<Timer> getDebuggerTimer;
    std::shared_ptr<Timer> getFileTimer;

In other words: he did not add an inclusion, but he added a reference to something the header does not know: class Timer.

In top of this, he added a shared pointer, which magically did something.

I'm completely lost here: it looks like STL has added programming rules like:
- In case you want something to work, don't add an inclusion, but add a reference (but how does your code know what the reference means?) - You can add shared pointers (or other STL inventions), who will make your code work.

?????

Can anybody shed a light to this?

Dominique
  • 16,450
  • 15
  • 56
  • 112
  • 5
    C# background? I'm asking because C++ doesn't define anything called "a property". It may help to clarify what you're trying to do. – Drew Dormann Mar 14 '18 at 14:16
  • And please give the complete error messages(s). – Richard Critten Mar 14 '18 at 14:17
  • 1
    I'm pretty sure this has nothing to do with templates or the STL. – juanchopanza Mar 14 '18 at 14:18
  • 4
    The STL is completely innocent here, I'm not sure what you're ranting about. – Mat Mar 14 '18 at 14:18
  • Take everything you learned about C# and then forget it if you want to learn C++. – Ron Mar 14 '18 at 14:19
  • 2
    Your boss should have been able to answer this question simply. Unless he gave you reasons for not asking, I'd say next time ask your boss about it instead of asking us :-) – Jeffrey Mar 14 '18 at 14:21
  • 3
    You're essentially missing a big chunk of C++ knowledge, among which "how to declare types". This whole question is just pointing fingers at random features that have nothing to do with the missing `#include` or declaration. Hence, VTC as "unlikely to help future readers". In your defense, MSVC's error message in this situation is incredibly unhelpful. – Quentin Mar 14 '18 at 14:26
  • Also, how is this any different from [this other Q&A of yours](https://stackoverflow.com/a/49030353/3233393)? – Quentin Mar 14 '18 at 14:33
  • "compiler errors C3646 and C4430" doesn't mean very much to anyone who's not using the same compiler as you. What's the exact (English) error message? – Toby Speight Mar 14 '18 at 21:22

2 Answers2

2

If you want to aggregate a Timer into your class defintion, the compiler needs to know what a Timer is. So, you could use #include "Timer.h"(use the right header).

What your boss did is two-fold

  1. use a pointer instead of a member object. Thus allowing it to work with a forward declaration instead of an include.
  2. use a smart pointer instead of a raw pointer. This is good practice.
Jeffrey
  • 11,063
  • 1
  • 21
  • 42
  • The `#include "Timer.h"` is not allowed because of circular references (although we don't find where that circular reference is: I've tried to upgrade my visual studio in order to have a graphical display of inclusions, but this caused my whole Visual Studio environment not to work anymore). – Dominique Mar 14 '18 at 14:24
  • 1
    That is a whole other question. On any large-scale project I've seen there was a facility for generating the inclusion tree. When a cycle is introduced (or attempted), you look up the tree and you use a clue bat where appropriate. In this case, it smells like Timer.h is inculding too much stuff. Because aggregating a Timer smells reasonable. – Jeffrey Mar 14 '18 at 14:27
  • But using a shared pointer is unlikely to be the best choice. – juanchopanza Mar 14 '18 at 14:52
0

This has nothing to do with template and STL.

You should look at what forward declaration is:

What your boss did with that

class Timer;

is to say to the compiler "hey look, there's something called Timer which you don't know yet, trust me and reserve for that some space".

Compiler answer ok, but it has to know how much space to allocate for costructing that object. Since you use an object and do not include the header file containing it, compiler doesn't know much space it takes and gives you an error. If you use a pointer instead (or smart pointer), the compiler does need to reserve only the space for a pointer and it can do it. Of coure then you have to include the header of time if you want to use it in the implementation.

For the same reason, you cannot forward declare a class you're going to inherit.

timer.h

class Timer
{
public:
   void time() { std::cout << "time!"; }
}

yourclass.h

class Timer; // forward declaration

class Manager
{
public:
  void doStuff() {}

private:
 Timer* t1; // this will work
 std::shared_pointer<Timer> t2; // this will work
 //Timer t3;  // this one don't
}

}

this case does not work:

class Timer;

class SpecialTimer : public Timer
{
 // ... do stuff
}

Some link about forward declaration:

https://en.wikipedia.org/wiki/Forward_declaration

This Post has a good explanation.

Moia
  • 2,216
  • 1
  • 12
  • 34