Defining a static member - c++

Consider the following code:
#include <iostream >
using namespace std;
class A
{
private:
int x;
public:
A(int _x) { x = _x; }
int get() { return x; }
};
class B
{
static A a;
public:
static int get()
{ return a.get(); }
};
A B::a(0);
int main(void)
{
B b;
cout << b.get();
return 0;
}
My book says:
If we do not use the line of code A B::a(0),there is a compiler error because static member a is not defined in B. To fix the error, we need to explicitly define a.
However, I thought of initializing object a as static A a(0); but it gives me a compiler error. Can someone explain why I can't initialize object a in the manner I described, and why it is necessary to initialize it as they had given it in book.

If you want to define a inline, you need to inline it, which is possible from C++17:
class B {
inline static A a{0}; // or inline static A a = 0;
public:
static int get() { return a.get(); }
};
Demo

Related

Accessing an inline function through a const member variable

I wanted to understand how the inline member variable work while accessing it through a const member variable.
Each time I try doing so, I get an error!
This is what I am trying
#include <iostream>
#include <string>
using namespace std;
class A{
public:
A()
{
_uuid = 0;
}
~A();
void setUUID(int n) { _uuid = n; }
inline int getUUID(){ return _uuid;} const
int getUUID1() const { return _uuid;}
int getUUIDsmart()const
{
return _uuid;
}
private:
int _uuid;
};
class B {
public:
B(){}
~B();
void fun1(const A *obj)
{
cout<<obj->getUUIDsmart()<<endl; //works fine
cout<<obj->getUUID1()<<endl; //works fine
cout<<obj->getUUID()<<endl; //error
A *obj1 = const_cast<A *>(obj);
cout<<obj1->getUUID()<<endl; //works fine
}
};
int main()
{
B *b = new B;
A *a = new A;
a->setUUID(12);
b->fun1(a);
}
I am able to get my code work through
const_cast
But I am interested in knowing why do i get an error in the inline function if I try accessing it through a const member function?
Update: FIX
My bad. I had the placement of const messed up!
Thanks to #bruno
inline int getUUID() const { return _uuid; }
//correct syntax. i placed the const at the end
[note : I use the first version of the question]
you place wrongly your const :
inline int getUUID(){ return _uuid;} const
int getUUID1(){ return _uuid;} const
int getUUIDsmart()const
is in fact
inline int getUUID(){ return _uuid;}
const int getUUID1(){ return _uuid;}
const int getUUIDsmart()const
I just moved the const on the right line for readability reason
You wanted
inline int getUUID() const { return _uuid;}
int getUUID1() const{ return _uuid;}
in your version none of getUUID1 nor getUUID are const so you cannot apply them on a const instance
There is no link at all with the fact your methods are inline or not.
Note :
cout<<obj->getUUID1()<<endl; //works fine
it doesn't

Communication between class data members in C++

Looking for how to best access class B's queue through A but I am receiving a segmentation fault. Also I am looking for the best way to communicate between these two classes. Are accessor methods ok in this scenario? What design pattern could work? Thanks
class B {
public:
int get_int() { return qi.front(); }
void put_int(int i) { qi.push(i); }
private:
queue<int> qi;
};
class A
{
public:
void get_event() { cout << b->get_int() << endl; }
void put_event(int a) { b->put_int(a); }
private:
B *b;
};
int main() {
A a;
a.put_event(1);
return 0;
}
As mentioned in comment problem is undefined initialization
you can fix that by using constructor for initialization
#include<iostream>
#include<queue>
using namespace std;
class B {
public:
int get_int() { return qi.front(); }
void put_int(int i)
{
qi.push(i);
}
private:
queue<int> qi;
};
class A
{
public:
void get_event() { cout << b->get_int() << endl; }
void put_event(int a) { b->put_int(a); }
A()
{
b = new B();
}
~A() { delete b; }
private:
B *b;
};
int main() {
A a;
a.put_event(1);
a.get_event();
return 0;
}
Output
1
Program ended with exit code: 0
A a;
is an undefined reference, you have to initialize it with a costructor and since you didn't defined any, you must use the default one
A a=new A();
or better, write the costructors of the two classes as you prefer and use them.

'B::operator A' uses undefined class 'A'

I have found the following example in one of my C++ courses. When I try to compile it I get the following error:
'B::operator A' uses undefined class 'A'
Why does it say that class A is undefined?
#include<iostream>
using namespace std;
class A;
class B
{
int x;
public: B(int i = 107) { x = i; }
operator A();
};
B::operator A() { return x; }
class A
{
int x;
public: A(int i = 6) { x = i; }
int get_x() { return x; }
};
int main()
{
B b;
A a = b;
cout << a.get_x();
system("Pause");
}
The compiler needs to know what A is here:
B::operator A() { return x; }
But you only have a forward declaration. You need to move the declaration of class A above B
You are only allowed to use pointers to or references of incomplete types which is what have when you forward declare a type
You need to declare A above B, so that the definition of A is visible to B.
#include<iostream>
using namespace std;
class A
{
int x;
public: A(int i = 6) { x = i; }
int get_x() { return x; }
};
class B
{
int x;
public: B(int i = 107) { x = i; }
operator A();
};
B::operator A() { return x; }
int main()
{
B b;
A a = b;
cout << a.get_x();
}
This should work.

How in C++ use templates to call specific members of supplied type

Lets assume we have two classes
struct A
{
int x = 1;
};
struct B
{
int y = 2;
};
I want to have template that will return value of member (in a case of A I want to return value of "x", in case of B I want to return value of "y").
Example call:
const auto myVariable = f<A>();
or
A a;
const auto myVariable = f<A>(a);
I don't want to have 2 template specializations - ideally it would be one template with some kind of "if statement", but maybe it is not possible?
It may be written with C++11 (but not with C++14).
Generally how you are using templates when you have such problems - quite big template and only in one or two places you need to take values from different members - which may be deduced based of type of that variable.
PROBLEM: unnecessary it is not allowed to modify classes A and B
Why use templates at all?
int f(const A& a) { return a.x; }
int f(const B& b) { return b.y; }
Just in case you ask for the template because you want to switch between A and B at compile time...and you have a reason not to simply typedef A or B directly...
struct A
{
int x;
};
struct B
{
int y;
};
struct A1 : public A { int Get() const { return x; } };
struct B1 : public B { int Get() const { return y; } };
// Begin possible shortcut avoiding the template below:
#ifdef USE_A
typedef A1 Bar;
#endif
#ifdef USE_B
typedef B1 Bar;
#endif
// End possible shortcut.
template <class _Base>
struct CompileTimeAOrB
: public _Base
{
int Get() const
{
return _Base::Get();
}
};
#define USE_A
//#define USE_B
#ifdef USE_A
typedef CompileTimeAOrB<A1> Foo;
#endif
#ifdef USE_B
typedef CompileTimeAOrB<B1> Foo;
#endif
EDIT: Since A and B cannot be changed, introduced A1, B1 ;)
#include <iostream>
struct A
{
int value;
A() : value(2) {}
};
struct B
{
int value;
B() : value(4) {}
};
template <typename T>
int GetValue(T t)
{
return t.value;
}
int main()
{
A a;
B b;
std::cout << GetValue(a) << std::endl;
std::cout << GetValue(b) << std::endl;
return 0;
}
In order for it to work, you'd need to have the same variable or function named declared in each class you wanted this to work with.

What does "name::name" means in C++?

I would like someone to explain me the "name::name" syntax and how it is used on C++ programming. I have been looking through but I don't get it yet. Thanks for help.
Here is context code:
void UsbProSender::SendMessageHeader(byte label, int size) const {
Serial.write(0x7E);
Serial.write(label);
Serial.write(size);
Serial.write(size >> 8);
}
:: is the scope resolution operator.
std::cout is the name cout in the namespace std.
std::vector::push_back is the push_back method of std::vector.
In your code example:
void UsbProSender::SendMessageHeader(byte label, int size) const {
Serial.write(0x7E);
Serial.write(label);
Serial.write(size);
Serial.write(size >> 8);
}
UsbProSender::SendMessageHeader is providing the definition for the SendMessageHeader method of the UsbProSender class.
Another (more complete) example:
class Bar {
int foo(int i); // forward declaration
};
// the definition
int Bar::foo(int i) {
return i;
}
It is operator for scope resolution.
Consider that code
class A { public: void f(){} };
class B { public: void f(){} };
class C : public A, public B {};
int main(int argc, char *argv[])
{
C c;
// c.f(); // ambiguous: which one of two f() is called?
c.A::f(); // OK
c.B::f(); // OK
return 0;
}