structs in libraries

Hi all;
I am trying to create a library with a struct. I am starting out simply, so my header file has;
class SourceModes
{
public:
typedef struct
{
int maxVal;
uint8_t scale;
uint8_t srcSnk;
uint8_t cvCc;
} srcModes_t;
};

Then the constructor in the cpp file has;

SourceModes::SourceModes (void) {
SourceModes::srcModes_t srcModes;
srcModes.maxVal = 1023;
srcModes.scale = 1;
srcModes.srcSnk = 0;
srcModes.cvCc = 0;
}

The arduino compiler gives me an error on the line
SourceModes::SourceModes (void) {
SourceMeter.cpp:14: error: definition of implicitly-declared 'SourceModes::SourceModes()'
I'm not sure how to create a class with only a struct, and no methods.
Does anyone have any idea what I'm doing wrong? Eventually I would like an array of structs that includes ints, and strings. Maybe that's just old school C and if there's a better cpp way, i'd try it.
Thanks for any help

You are able to do this:

class SourceModes
{
public:
typedef struct
   {
   int maxVal;         
   uint8_t scale;            
   uint8_t srcSnk;      
   uint8_t cvCc;      
   }   srcModes_t;      
};

Then the constructor in the cpp file has;

SourceModes::SourceModes (void) {
srcModes_t srcModes;
   srcModes.maxVal = 1023;
   srcModes.scale = 1;
   srcModes.srcSnk = 0;
   srcModes.cvCc = 0;
}

But this is NOT what you want. The struct srcModes is a temporary variable defined inside the constructor and will be out of scope as soon as the constructor returns. You want to move the srcModes_t srcModes; to your class definition so srcModes becomes a member variable of the class. A struct is treated like a class in c++ so if you just do a struct definition, you can do new and everything with the structs as if it were a class definition. By default, a member in a class is private unless you list it under public. By default, a member in a struct is public unless you list it under private. :slight_smile:

Why is the struct defined as nested struct of SourceModes? You can do it but I'm wondering if you really want to do it. The reason compiler gives you error is because you don't define default constructor of SourceModes in the class definition, but again I don't know if you really want to do it since the implementation is just weird. Do you want to define default constructor for the struct to set its default values upon construction? In that case just define the default constructor for the struct instead. If you are maiking a lib and want to avoid naming clashes, you should rather use namespace than a class. Your struct definition is also oldschool C so rather use the c++ way. So, to "fix" what you are doing based on these assumptions, do:

namespace SourceModes
{
  struct srcModes_t
  {
    srcModes_t();
    int maxVal;
    ...
  };
}

And in the cpp:

SourceModes::srcModes_t::srcModes_t()
{
  // init srcModes_t variables here
}

It is nothing to do with the nested struct,

You are defining a constructor without a declaration, either remove it or add a declaration in the SourceModes class, not the class srcModes_t.

SourceModes( void );

the typedef is creating an anonymous struct, use:

class SourceModes
{
  
public:

SourceModes (void);
 struct srcModes_t
   {
     int maxVal;         
     uint8_t scale;            
     uint8_t srcSnk;      
     uint8_t cvCc;      
   };      
};


SourceModes::SourceModes (void) {
SourceModes::srcModes_t srcModes;
   srcModes.maxVal = 1023;
   srcModes.scale = 1;
   srcModes.srcSnk = 0;
   srcModes.cvCc = 0;
}

However liudr is correct about the local variable.

EDIT: confused my self with the typedef, but still fixed.

Doesn't sound like OP wants to define constructor for SourceModes though but default constructor of srcModes_t. Also sounds OP is confused of having to define structs as nested classes for a lib, which obviously is not a case. SourceModes is used as a namespace and should be changed to namespace instead if the intention is to avoid name clashes

JarkkoL:
Doesn't sound like OP wants to define constructor for SourceModes though but default constructor of srcModes_t. Also sounds OP is confused of having to define structs as nested classes for a lib, which obviously is not a case. SourceModes is used as a namespace and should be changed to namespace instead if your intention is to prevent name clashes

It is in their code example:

SourceModes::SourceModes (void) {
SourceModes::srcModes_t srcModes;
   srcModes.maxVal = 1023;
   srcModes.scale = 1;
   srcModes.srcSnk = 0;
   srcModes.cvCc = 0;
}

A member of srcModes_t in SourceModes will fix the local variable.

It is in their code example:

Sure, but that's totally useless constructor thus I believe that's not what OP wants to do :wink: Anyway, too much guessing so maybe OP could clarify his intentions

Hi everyone, thanks for all the comments. Sorry to be so confused, but OOP is still quite a mystery for me. I am not trying to create nested structs. I really just want to add structs to a library so I can use them in my sketches, but wasn't sure how to do it in cpp.
What pYro_65 wrote looks like what I was trying to do. Just a simple struct - that typdef was a real mistake. I think I see what I am doing wrong. You guys are a great help Thanks!!!

That's what I thought :wink: Just get rid of the whole SourceModes class since you don't need it for anything. So, your code should look like this:

struct srcModes_t
{
  srcModes_t();
  int maxVal;         
  uint8_t scale;            
  uint8_t srcSnk;      
  uint8_t cvCc;      
};

And in cpp:

srcModes_t::srcModes_t()
{
  maxVal = 1023;
  scale = 1;
  srcSnk = 0;
  cvCc = 0;
}

When writing constructors remember to use inita;ization lists instead setting member variables in the body of the constructor.

srcModes_t::srcModes_t() : maxVal(1023), scale(1), srcSnk(0), cvCc(0)
{   }

Doesn't make any difference in this case though. Initializer lists are useful if you need to construct const/reference member variables, or class types with non-default constructor to avoid unnecessary default construction. Doesn't really hurt to use initializer list though, unless if you have multiple constructors doing the same thing (duplicate code).

thanks for the tip, but I am still a little confused about this one. What does this do?

struct srcModes_t
{
  srcModes_t();

?? generally structs use the construction:

struct <struct name>{
 <member type 1 > <member name 1>
etc.
} object names;

so I am trying to create a stuct named srcModes_t then use that definition to create an object named srcModes. So how would I access these members in a sketch?

When I try to use the class defined in pYro_65's code. The .h and .cpp files compile, but when I create an instance of the class in my sketch;

#include <SourceMeter.h>
SourceModes smodes;

then try to access a member:

Serial.print (smodes.srcModes.maxVal);

I get the error: 'class SourceModes' has no member named 'srcModes'
Did I not create the instance correctly, or did I somehow not include the struct as part of the class?
Thanks again.

You create the instance like this:

srcModes_t smodes;
Serial.print(smodes.maxVal);

Oh, and strModes_t() within the struct defines the default constructor. That gets called when you create the instance and initializes the struct variables to the defaults. You don't have to define it, but it's just common practice to have some default instead of garbage values.

Thanks to all, the simple approach seems to be working.