So I want to add a struct from a c header file as a class member to a c++ class.
But I get a compiler error for the cpp file: bar was not declared inn this scope.
This is what I have:
//    myClass.hpp
#include fileWithStruct.h
class myClass
{
    public:
        struct foo bar;
};
//myClass.cpp
#include "myClass.hpp"
//Initialize structure in Constrcutor
myClass::myClass(  )
{
    bar = {1, 0, "someString", 0x4};
}
                For instance, with this struct: struct Point { int x; int y; int z; }; We can initialize an instance with the following syntax: Point p = {1, 2, 3};
Use a[i] = new myClass() in your loop. This 0-argument constructor for class myClass will be generated by Java. Names of the classes in Java are written LikeThis by convention.
When initializing a struct, the first initializer in the list initializes the first declared member (unless a designator is specified) (since C99), and all subsequent initializers without designators (since C99)initialize the struct members declared after the one initialized by the previous expression.
An initializer for a structure is a brace-enclosed comma-separated list of values, and for a union, a brace-enclosed single value. The initializer is preceded by an equal sign ( = ).
#include "fileWithStruct.h" /* say the contents were struct foo {    int foo1;    float foo2; }; */  class myClass {     public:         int val;         foo bar;         // since foo is a POD-struct (a.k.a C struct), no constructor would be present         // however bar() will zero-initialize everything in the struct         myClass() : val(), bar()         {         } };   The parentheses following bar matters. Refer value and zero-initialization to understand why this works. It is to be noted that by adding a constructor to myClass, we've made it a non-POD type. To work around this, one can retain myClass as an aggregate and write:
class myClass {     public:         int val;         foo bar; };  int main() {    myClass zeroed_obj = { };    myClass inited_obj = { 2, {0, 1.0f} };    myClass partially_inited_obj = { 2 };    // equivalent to {2, {}}; which would zero all of myClass::bar    myClass garbage_obj;    // warning: when left uninitialized, every member without a constructor will end up with garbage value }   class myClass { public:    // default member initializations    int val = { };         // zero-initialization    foo bar = { 0, 0.0f }; // aggregate-initializing foo here, just giving { } will zero all of myClass::bar     // should you want to receive an element from the constructor, this can be done too    // aggregate initializing a struct in constructor initialization list is allowed from C++11 onwards    // in C++03, we would've resorted to just setting the member of bar inside the constructor body    myClass(int _foo1) : val{}, bar{_foo1, 0.f}    {    }     // since we've a non-default constructor, we've to re-introduce the default constructor    // if we need the above in-class initialization to work    myClass() = default; };   Here we use C++11's uniform initialization syntax. However, by doing this myClass becomes a non-POD type; member initialization is akin to adding a constructor to the class, thereby rendering myClass a non-trivial but standard-layout class. As per C++11 for a class to be POD it should be both trivial and standard-layout. Instead doing
#include "fileWithStruct.h" #include <type_traits> #include <iostream>  class myClass { public:    int val;    foo bar; };  int main() {     myClass obj { }; // initializes val, bar.foo1 and bar.foo2 to 0     myClass m { 0, {1, 2.0f} }; // initilizes each member separately     std::cout << std::is_pod<myClass>::value << std::endl; // will return 1 }   will retain myClass as a POD.
Refer to this excellent post to know more about aggregates and PODs.
What you are doing there is assignment, not initialization. Initialization happens in the initialization list of a constructor, before the constructor body, or in C++11 in an initializer right after the member variable declaration:
myClass.hpp, general case:
/** you might want to do this if you are linking 
 * against the C lib or object file of that header:
 */
extern "C" { 
  #include fileWithStruct.h
}
class myClass
{
public:
  foo bar; //no need for "struct" in C++ here
};
myClass.cpp
#include "myClass.hpp"
//Initialize structure in Constrcutor
myClass::myClass(  )
  : bar{1, 0, "someString", 0x4}
{}
Antoher option is to provide the initial value of foo with an brace-or-equal-initializer at the member variable declaration:
myClass.hpp
extern "C" { 
  #include fileWithStruct.h
}
class myClass
{
public:
  foo bar{1, 0, "someString", 0x4};
};
In this case, you need not define a constructor, since it's generated implicitly by the compiler (if needed), correctly initializing bar.
Here aggregate initialization in init lists is not available, so you have to use workarounds, e.g.:
myClass.cpp
#include "myClass.hpp"
//Initialize structure in Constrcutor
myClass::myClass(  )
  : bar() //initialization with 0
{
  const static foo barInit = {1, 0, "someString", 0x4}; //assignment
  bar = barInit;
}
Or:
#include "myClass.hpp"
namespace {
  foo const& initFoo() {
    const static foo f = {1, 0, "someString", 0x4};
    return f;
  }
}
//Initialize structure in Constrcutor
myClass::myClass(  )
  : bar(initFoo()) //initialization
{ }
                        Initialization should be done this way (C++11):
myClass::myClass(  )
: bar{1, 0, "someString", 0x4}
{
}
Also, do not forget to declare your constructor in your class definition.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With