Add static const data to a struct already defined - c++

Since static const data inside a class is really just namespace sugar for constants I would think that
struct A {
float a;
struct B {
static const int b = 2;
};
};
would be equivalent to
struct A {
float a;
};
struct A::B {
static const int b = 2;
};
or something similar. Is something like this possible in C++? It would be useful for me to be able to tag class definitions that I'm pulling in from third party libraries with information like this.

You can't reopen struct/class definitions in C++, so the best you can do is create derived versions of the third party structs and add your constants that way:
struct My_A : public A
{
static const int b = a;
};
Otherwise, you could maintain a map of your constants with keys based on struct typeid.
I do like Georg's idea as well.

No, you can't just redefine classes that way.
If you want to tag already defined classes, you could do that non-intrusively using e.g. template specializations:
template<class T> struct tagged;
template<> struct tagged<A> {
static const int b = 42;
};

Related

Why do we use typedef in structure when we have a shorter method

When I define some random structure like for example in a cpp file in Visual studio
1) struct CAddition {
int x, y;
CAddition(int a, int b) { x = a; y = b; }
int result() { return x + y; }
};
and now if I define some structure object
CAddition foo;
it works without any error
but if I use any alias in the end
2) struct CAddition {
int x, y;
CAddition(int a, int b) { x = a; y = b; }
int result() { return x + y; }
}CAddition;
I cannot simply define any object without using struct before the definition
struct CAddition foo;
or an alternative method would be to add
typedef struct CAddition {
In the method 2 to avoid rewriting struct every time , My question is whats the difference between these 2 definitions , doesn't method 1 use less keywords and much easier to use in what conditions should we use the second definition of a structure.
With struct CAddition { ... } CAddition; you are doing two things:
You define the structure CAddition as a typename. That's what the struct CAddition thing does.
You define the variable CAddition. The variable is the one after the structure.
Because you define the variable CAddition you can not use that name for the type, as then the compiler will think you mean the variable and not the structure. To solve this you need to use struct CAddition to explicitly tell the compiler you mean the structure typename.
On an unrelated note: A struct is just like a class, with the difference being that all members a public by default in a struct. So you don't need the public specification in a struct.
it works without any error but if I use any alias in the end
In 2) you are not using an "alias", but you create an instance of that class you just defined (structs and classes are the same in c++ btw). You then have an instance with a name that shadows the class name and as a consequence you need the struct CAddtion to tell the compiler that CAddition refers to the class not to the instance you created.

Shorten Member Function Scope Specifiers (Nested Classes) (C++)

Suppose I have nested classes as follows defined in a header file:
class ClassA
{
private:
class ClassB
{
private:
int member_b;
public:
void function_name();
};
};
In order to give a definition to the function "function_name()" in an external .cpp file, I have to access it like this:
void ClassA::ClassB::function_name()
{
std::cout << member_b;
return;
}
For the sake of this example, please do not ask why I'm using nested classes; I have a reason for doing so in my actual project. However, my question is this; is it possible to somehow shorten the ClassA::ClassB::function_name() in the implementation file to something like short::function_name() while still keeping the classes nested? I don't think that typedefs or new namespace definitions can help me here, but maybe I'm wrong.
Qualified type names allow you to define a typedef to represent a qualified class name. You can then use the typedef with the :: (scope resolution) operator to refer to a nested class or class member, as shown in the following example:
class outside
{
public:
class nested
{
public:
static int x;
static int y;
int f();
int g();
};
};
int outside::nested::x = 5;
int outside::nested::f() { return 0; };
typedef outside::nested outnest; // define a typedef
int outnest::y = 10; // use typedef with ::
int outnest::g() { return 0; };
However, using a typedef to represent a nested class name hides information and may make the code harder to understand.
Source : https://www.ibm.com/support/knowledgecenter/en/SSPSQF_9.0.0/com.ibm.xlcpp111.aix.doc/language_ref/cplr061.html
Have you tried using aliases?
// C++11
using fmtfl = std::ios_base::fmtflags;
// C++03 equivalent:
// typedef std::ios_base::fmtflags fmtfl;
fmtfl fl_orig = std::cout.flags();
fmtfl fl_hex = (fl_orig & ~std::cout.basefield) | std::cout.showbase | std::cout.hex;
// ...
std::cout.flags(fl_hex);
Code source: https://msdn.microsoft.com/en-us/library/dn467695.aspx

How to use structs declared private?

I'm working on a project with a pre-made .hpp file with all the declarations and stuff.
A struct is declared in the private part of the class, along with some private members.
I need to create an array with the type of the struct in my .cpp file.
//.hpp
private:
struct foo
{
std::string a;
unsigned int b;
};
std::string* x;
unsigned int y;
//.cpp
unsigned int returny()
{
return y; // No errors
}
foo newArray[10]; // Compile time error; unknown type name
Why is it that I can return y, which is also private, but not make an array out of the struct foo?
How can I fix this? (I'm in an introductory C++ class... so hopefully there's a simple solution)
There are couple of issues.
You can't use a type that's defined in the private section of class like you are trying.
The nested type can be used by specifying the appropriate scope.
EnclosingClass::foo newArray[10];
But this will work only if foo is defined in the public section of EnclosingClass.
you should define the struct int the outside of the class like this
struct Foo
{
std::string a;
unsigned int b;
};
class A {
private:
Foo foo;
...
}

Struct Constructor in C++?

Can a struct have a constructor in C++?
I have been trying to solve this problem but I am not getting the syntax.
In C++ the only difference between a class and a struct is that members and base classes are private by default in classes, whereas they are public by default in structs.
So structs can have constructors, and the syntax is the same as for classes.
struct TestStruct {
int id;
TestStruct() : id(42)
{
}
};
All the above answers technically answer the asker's question, but just thought I'd point out a case where you might encounter problems.
If you declare your struct like this:
typedef struct{
int x;
foo(){};
} foo;
You will have problems trying to declare a constructor. This is of course because you haven't actually declared a struct named "foo", you've created an anonymous struct and assigned it the alias "foo". This also means you will not be able to use "foo" with a scoping operator in a cpp file:
foo.h:
typedef struct{
int x;
void myFunc(int y);
} foo;
foo.cpp:
//<-- This will not work because the struct "foo" was never declared.
void foo::myFunc(int y)
{
//do something...
}
To fix this, you must either do this:
struct foo{
int x;
foo(){};
};
or this:
typedef struct foo{
int x;
foo(){};
} foo;
Where the latter creates a struct called "foo" and gives it the alias "foo" so you don't have to use the struct keyword when referencing it.
As the other answers mention, a struct is basically treated as a class in C++. This allows you to have a constructor which can be used to initialize the struct with default values. Below, the constructor takes sz and b as arguments, and initializes the other variables to some default values.
struct blocknode
{
unsigned int bsize;
bool free;
unsigned char *bptr;
blocknode *next;
blocknode *prev;
blocknode(unsigned int sz, unsigned char *b, bool f = true,
blocknode *p = 0, blocknode *n = 0) :
bsize(sz), free(f), bptr(b), prev(p), next(n) {}
};
Usage:
unsigned char *bptr = new unsigned char[1024];
blocknode *fblock = new blocknode(1024, btpr);
Class, Structure and Union is described in below table in short.
Yes, but if you have your structure in a union then you cannot. It is the same as a class.
struct Example
{
unsigned int mTest;
Example()
{
}
};
Unions will not allow constructors in the structs. You can make a constructor on the union though. This question relates to non-trivial constructors in unions.
In c++ struct and c++ class have only one difference by default struct members are public and class members are private.
/*Here, C++ program constructor in struct*/
#include <iostream>
using namespace std;
struct hello
{
public: //by default also it is public
hello();
~hello();
};
hello::hello()
{
cout<<"calling constructor...!"<<endl;
}
hello::~hello()
{
cout<<"calling destructor...!"<<endl;
}
int main()
{
hello obj; //creating a hello obj, calling hello constructor and destructor
return 0;
}
Yes. A structure is just like a class, but defaults to public:, in the class definition and when inheriting:
struct Foo
{
int bar;
Foo(void) :
bar(0)
{
}
}
Considering your other question, I would suggest you read through some tutorials. They will answer your questions faster and more complete than we will.
Note that there is one interesting difference (at least with the MS C++ compiler):
If you have a plain vanilla struct like this
struct MyStruct {
int id;
double x;
double y;
} MYSTRUCT;
then somewhere else you might initialize an array of such objects like this:
MYSTRUCT _pointList[] = {
{ 1, 1.0, 1.0 },
{ 2, 1.0, 2.0 },
{ 3, 2.0, 1.0 }
};
however, as soon as you add a user-defined constructor to MyStruct such as the ones discussed above, you'd get an error like this:
'MyStruct' : Types with user defined constructors are not aggregate
<file and line> : error C2552: '_pointList' : non-aggregates cannot
be initialized with initializer list.
So that's at least one other difference between a struct and a class. This kind of initialization may not be good OO practice, but it appears all over the place in the legacy WinSDK c++ code that I support. Just so you know...
One more example but using this keyword when setting value in constructor:
#include <iostream>
using namespace std;
struct Node {
int value;
Node(int value) {
this->value = value;
}
void print()
{
cout << this->value << endl;
}
};
int main() {
Node n = Node(10);
n.print();
return 0;
}
Compiled with GCC 8.1.0.
struct HaveSome
{
int fun;
HaveSome()
{
fun = 69;
}
};
I'd rather initialize inside the constructor so I don't need to keep the order.
Syntax is as same as of class in C++. If you aware of creating constructor in c++ then it is same in struct.
struct Date
{
int day;
Date(int d)
{
day = d;
}
void printDay()
{
cout << "day " << day << endl;
}
};
Struct can have all things as class in c++. As earlier said difference is only that by default C++ member have private access but in struct it is public.But as per programming consideration Use the struct keyword for data-only structures. Use the class keyword for objects that have both data and functions.
Yes structures and classes in C++ are the same except that structures members are public by default whereas classes members are private by default. Anything you can do in a class you should be able to do in a structure.
struct Foo
{
Foo()
{
// Initialize Foo
}
};
Yes it possible to have constructor in structure here is one example:
#include<iostream.h>
struct a {
int x;
a(){x=100;}
};
int main() {
struct a a1;
getch();
}
In C++ both struct & class are equal except struct'sdefault member access specifier is public & class has private.
The reason for having struct in C++ is C++ is a superset of C and must have backward compatible with legacy C types.
For example if the language user tries to include some C header file legacy-c.h in his C++ code & it contains struct Test {int x,y};. Members of struct Test should be accessible as like C.
In C++, we can declare/define the structure just like class and have the constructors/destructors for the Structures and have variables/functions defined in it.
The only difference is the default scope of the variables/functions defined.
Other than the above difference, mostly you should be able to imitate the functionality of class using structs.

Namespacing (static) member variables

I would like to be able to achieve something like this:
class Zot
{
namespace A
{
static int x;
static int y;
}
}
I am working with a legacy system that uses code generation heavily off a DB schema, and certain fields are exposed as methods/variables in the class definition. I need to add a few extra static variables to these classes and would like to guarantee no clashes with the existing names.
The best I have come up with is to use another struct to wrap the statics as if it were a namespace:
class Zot
{
struct A
{
static int x;
static int y;
}
}
Is there a better way?
Update:
An extra requirement is to be able to access these from a template elsewhere
e.g.
template<class T>
class B
{
void foo() { return T::A::x; }
};
So putting them in a separate class won't work
Really the inner struct is your best bet. Another possibility would be to use a typedef to bring in a class of statics. This works well for code generation in that you can separate the extras from the generated code:
In the generated file that doesn't care at all what's in Zot_statics:
class Zot_statics;
class Zot
{
public:
typedef Zot_statics A;
int x; // This is ok
};
In a hand-maintained header for when you need to access x and y:
class Zot_statics
{
public:
static int x;
static int y;
};
In a hand-maintained cpp file:
int Zot_statics::x;
int Zot_statics::y;
And your template should work just fine with Zot::X referring to the instance variable X on Zot, and Zot::A::x refering to the static variable.