Understanding namespace and include.

I think I can best explain my confusion by walking you through the code that confused me:

1
2
3
m_bpaVerInfo = makeVersionString(TJM::bpa().firmwareVersion(),
                                       TJM::bpa().protocolVersion(),
                                       TJM::bpa().haveCompatibleDevice());


So TJM is a namespace so I believe that means if I put methods inside of TJM then I can access those methods from outside of my current class with the ::, hence:

TJM::bpa()

seems to read: "The TJM namespace has a method called bpa() inside of it", which it sort of does. It actually seems more like a constructor.

So then I go to take a look at firmwareVersion():

1
2
3
4
5
6
7
8
9
  const CVersionTag* BpaProvider::firmwareVersion() const
  {
    switch (m_providerType)
    {
      case SdmProvider       : return sdm().firmwareVersion();
      case DynamicSdmProvider: return dynamicSdm().firmwareVersion();
      case NoProvider        : break;
      PROHIBIT_DEFAULT:        break;
    }


First thing I see is that this method is accessing another method with the exact same name which in my mind is blasphemy but apparently c++ is the wild west lol

At this point, in my mind: bpa().firmwareVersion() means: "Go to the bpa() class and look for a method called firmwareVersion()". Therefore, when I saw: dynamicSdm().firmwareVersion(); I thought: "Ah, there must be a class called firmwareVersion within a class called dynamicSdm()!" and it must be part of the TJM namespace (hence why they can be named the same thing).

Wrong! Instead, firmwareVersion is declared in a script called ModuleBase_Qt.h. However, sdm() or rather SdmProvider.cpp isn't even including ModuleBase_Qt.h so how is it accessing the method?

Then I remembered c++ allows inception of header files. So should I check every include inside of SdmProvider.cpp to look and see if one of the includes within that file is including ModuleBase_Qt.h? Or is there another way SdmProvider might be accessing firmwareVersion from within the ModuleBase_Qt header file that has less to do with header files and more to do with namespace?
Last edited on
Can we agree that:
- a method is a function which is member of a class
and:
- if a function is declared outside a class, it’s better to refer to it simply as a ‘function’ ?

If we agree with what above:
So TJM is a namespace so I believe that means if I put methods inside of TJM then I can access those methods from outside of my current class with the ::

The namespace doesn’t modify the ‘traditional’ way to access class members.
To invoke a non static method you need a class instance; to invoke a static method, you anyway need the class name.

Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
namespace vysero {


struct MyClass {
    void method_a();
    static void method_b();
};


// From inside namespace vysero:
MyClass my_instance;
my_instance.method_a();
MyClass::method_b();


} // end namespace vysero


// From outside namespace vysero:
vysero::MyClass my_instance;
my_instance.method_a();
vysero::MyClass::method_b();


bpa().firmwareVersion() means: "Go to the bpa() class

I apologize for the following stupid questions, but they are quite typical in guessing games:
Are you sure TJM is a namespace?
Are you sure in that namespace there’s declared a class bpa?
Are you sure bpa() is not just a function (no matter if member of a class or not)?

About your second snippet...
It’s possible that both bpa and BpaProvider were part of an inheritance chain, so that sdm() and dynamicSdm() return instance of different classes, in the same chain, which expose different versions of firmwareVersion()... Who knows?
But, from my limited experience, is not that common that trained programmers adopt inconsistent naming conventions, such as calling some classes with a capitalized name and others with a lowercase initial.

What about adding some code (an entire header, for example)?
I think I can answer all four questions with a code snippet:

1
2
3
4
5
6
7
8
9
10
namespace TeeJetModules
{  
  BpaProvider&  bpa()
  {
    static BpaProvider  instance;
    return instance;
  }

  
  BpaProvider::BpaProvider()


that is the deceleration for bpa() inside of the BpaProvider.cpp script.

On a side note, I find it odd that a header file would contain definitions for functions that are not being instantiated inside of the .cpp file for that particular header. Is this common practice in c++? For instance, at the end of my last post, I was asking about the inception of headers. I do believe this is what's happening here: sdm().firmwareVersion();

I believe firmwareVersion is being accessed by sdm() via an inception of headers. In any case, the reason I am asking is because I noticed that firmwareVersion() is declared within TeeJetModuleBase_Qt.h:

virtual const CVersionTag* firmwareVersion() const { return &m_firmwareVer; };

however, the function is not instantiated in TeeJetModuleBase_Qt.cpp which I find odd. That means either sdm() can access firmwareVersion() with only a deceleration inside the header file or there is a different firmwareVersion() and my IDE is just confused.

Last edited on
vysero wrote:
So TJM is a namespace so I believe that means if I put methods inside of TJM then I can access those methods from outside of my current class with the ::, hence:

TJM::bpa()

seems to read: "The TJM namespace has a method called bpa() inside of it", which it sort of does. It actually seems more like a constructor.
vysero wrote:
1
2
3
4
5
6
7
8
9
10
namespace TeeJetModules
{  
  BpaProvider&  bpa()
  {
    static BpaProvider  instance;
    return instance;
  }

  
  BpaProvider::BpaProvider()

As you can see, bpa is neither a class nor a method.
Does it resemble a constructor? Well, that’s personal, but constructors return nothing.

“dynamicSdm()” is likely to be the same thing, and that clarifies how the second snippet in the first post works.

vysero wrote:
at the end of my last post, I was asking about the inception of headers

I’ve googled by the words “c++ inception of headers” and haven’t spot any page where ‘headers’ and ‘inception’ appear together, so I can’t be of any help on this.

Is it possible that you’re asking about header inclusion?

vysero wrote:
In any case, the reason I am asking is because I noticed that firmwareVersion() is declared within TeeJetModuleBase_Qt.h:

virtual const CVersionTag* firmwareVersion() const { return &m_firmwareVer; };

however, the function is not instantiated in TeeJetModuleBase_Qt.cpp which I find odd.

Functions are not instantiated, they are invoked (or called).
Let’s say that method is defined inline in the header.

vysero wrote:
my IDE is just confused

Me too.

I really think you’d get far better help if you posted the entire headers and asked about specific problems you’re facing.
Alright well the specific problem I have is that this code is working:

1
2
3
4
5
6
7
8
9
10
11
12
 const CVersionTag* BpaProvider::firmwareVersion() const
  {
    switch (m_providerType)
    {
      case SdmProvider       : return sdm().firmwareVersion();
      case DynamicSdmProvider: return dynamicSdm().firmwareVersion();
      case NoProvider        : break;
      PROHIBIT_DEFAULT:        break;
    }

    return &m_emptyVersion;
  }


but this is not:

1
2
3
4
5
6
7
8
9
10
11
12
 const CVersionTag* BpaProvider::firmwareVersion() const
  {
    switch (m_providerType)
    {
      case SdmProvider       : return sdm().firmwareVersion();
      case DynamicSdmProvider: return dynamicSdmSlaves().firmwareVersion();
      case NoProvider        : break;
      PROHIBIT_DEFAULT:        break;
    }

    return &m_emptyVersion;
  }


and is producing an error:

error: 'dynamicSdmSlaves' was not declared in this scope

Which is confusing because dynamicSdm() has no deceleration inside of BpaProvider.cpp. Which is why I was thinking it must be usable in this scope because of the TJM namespace.

All three of these functions: bpa(), dynamicSdm() and dynamicSdmSlaves() are declared the same way:

1
2
3
4
5
6
7
namespace TeeJetModules
{  
  BpaProvider&  bpa()
  {
    static BpaProvider  instance;
    return instance;
  }


1
2
3
4
5
6
7
namespace TeeJetModules
{  
  DynamicSdmProvider&  dynamicSdm()
  {
    static DynamicSdmProvider  instance;
    return instance;
  }


1
2
3
4
5
6
7
8
namespace TeeJetModules
{

  DynamicSdmSlaveProvider&  dynamicSdmSlaves()
  {
    static DynamicSdmSlaveProvider instance;
    return instance;
  }


in their respective .cpp files.

Along the same lines this code works:

TJM::bpa().firmwareVersion()

but this does not:

TJM::dynamicSdmSlaves().firmwareVersion()

but gives a different error:

error: 'dynamicSdmSlaves' is not a member of 'TJM'

how can it not be a member if it's created inside the namespace?
Last edited on
... this code

dynamicSdmSlaves().firmwareVersion();

... is producing an error:

error: 'dynamicSdmSlaves' was not declared in this scope

Do check if you have included the scope where dynamicSdmSlaves() is declared inside the scope where it is invoked. You’re probably be missing some header or you’re calling it from outside its namespace.

Which is confusing because dynamicSdm() has no deceleration inside of BpaProvider.cpp.

There are usually no declarations inside cpp files, there are usually definitions. And, as a matter of fact, you post it few rows below ;-)
Even if splitting function prototypes from their definitions is a good practice, it’s not mandatory: as far as I know, you just need to guarantee the function is well defined before you invoke it.

Which is why I was thinking it must be usable in this scope because of the TJM namespace.

Namespaces themselves don’t change the ‘normal relationship’ between declarations and definitions - they indeed modify their scope, but declarations and definitions must anyway be there!

All three of these functions ... are declared the same way ... in their respective .cpp files.

Do you mean they are defined? That definition can also stand in for a declaration.

... this code ...
TJM::dynamicSdmSlaves().firmwareVersion()
... gives ...
error: 'dynamicSdmSlaves' is not a member of 'TJM'
how can it not be a member if it's created inside the namespace?

Again: it is not created, it is defined.
Anyway: cannot guess, need to see the entire code. It could just be a simple problem of missing headers.

May I say you’re doing your best to make your questions incomprehensible?
If the namespace is called ‘TeeJetModules’, why do you insist in modifying its name in ‘TJM’ inside the post?

And how could we guess what has been properly declared and defined and why something is not in the same scope of another thing if we cannot see the entire code?
It seems I was confused about a few things. I wasn't aware that I would need to place the header file for DynamicSdmSlaveProvider inside of BpaProvider because I thought header inclusion meant that since DynamicSdmProvider had an include for DynamicSdmSlaveProvider then I would have access to it. I didn't modify the name of TeeJetModules in this thread:

namespace TJM = TeeJetModules;

is in the code.

Also, I don't believe English is your first language, is it? That would probobly explain why you feel my questions are: "incomprehensible". Or maybe it is my lack of understanding of the Jargon I am trying to use that confuses you, can't be sure.
Last edited on
Topic archived. No new replies allowed.