We have classes A, B and C, all of which need access to a static variable staticVariable in class D.
Moreover, class A needs to have an instance of classes B and C like this:
class A{
public:
B instanceB;
C instanceC;
};
Class D hold the static variable of object type T:
class D{
public:
D() {
staticVariable.init();
};
static T staticVariable;
};
In the example classes B and C can be empty placeholder classes:
class B{
};
class C{
};
The main function creates an instance of A:
int main(){
A a;
/*...*/
}
Again, classes A, B and C need access to staticVariable. I've tried multiple approaches including inheritance and friend functions, however I always get dependency issues or linker errors I don't quite understand:
Error LNK2001 unresolved external symbol "public: static class T
D::staticVariable" (?window#D##2VT#sf##A) SortingAlgorithms
C:\Users\Dusan\source\repos\SortingAlgorithms\SortingAlgorithms\B.obj
is being reported in .obj files of classes A, B and C.
I'm not sure if I need an instance of D in main.
How do I implement this error-free?
And how do you do it for static objects that call a function for initialization?
I meant if the function is of the same class as the object you're trying to initialize, and is non-static, I can't seem to be able to call staticVariable.init();
I'm not sure if I need an instance of D in main.
You don't. static variables are global, they are shared by all the instances of the same class and you don't need to instantiate a class to be able to use such variables so they must be initialized regardless of class instantiation. That being the case they need to be initialized outside the class.
How do I implement this error-free?
Something like:
class B{};
class C{};
class A{
public:
B instanceB;
C instanceC;
};
class D{
public:
D(){};
static int staticVariable;
};
int D::staticVariable = 10; //<-- here, outside the class
int main()
{
//no instance of D needed
std::cout << D::staticVariable; // prints 10
D::staticVariable++;
std::cout << D::staticVariable; // prints 11
}
And how do you do it for static objects that call a function for initialization?
I meant if the function is of the same class as the object you're trying to initialize, and is non-static, I can't seem to be able to call staticVariable.init();
It's the same principle, you declare the object static within the class and initialize it outside:
class A{
public:
void init(){std::cout << "Do Something";} //non-static method
};
class D{
public:
static A obj; //declare
};
A D::obj{}; //<-- initialize outside the class
int main()
{
D::obj.init(); // prints 'Do Something'
}
// in D.hpp
class D {
public:
D() { ... }; // staticVariable is static, so the ctor has no business initializing it
void init();
static int staticVariable;
static D staticD;
};
// in D.cpp
#include "D.hpp"
int D::staticVariable = 10;
// Immediatly invoked initializing lambda expression
D D::staticD = []{ D tmp; tmp.init(); return tmp; }();
Related
So i have been trying to use derived class data members from the base class and i am not able to figure out how to do that. I see a way to do this as just passing the member i need in parameter when i call the base class method but i was just thinking that there should be another way to do that. So i have replicated this as below.
#include<iostream>
using namespace std;
class B;
class A{
public:
display(){
cout<<cord<<endl;
}
int cord = 25;
};
class B : public A{
public:
B(){
A a;
a.display();
}
int cord = 30;
};
class C : public A{
public:
C(){
A a;
a.display();
}
int cord = 35;
};
int main(){
B b;
C c;
B.display();
}
The above code as giving output as
25
25
25
What i want it to give out is
30
35
30
Every way to do this will be appreciated, whatever is better and if you want to me add something or anything ask in comments, i'll do right away.
define a virtual getter like
virtual int getCord() const { return cord; }
in each class and call it in display
void display(){ cout << getCord() <<endl; }
and in the constructor of B and C you also need to replace
A a;
a.display();
just by
display();
else there is no chance you access to the value of the sub classes explicitly calling display on an instance of A
using derived class data members from base class method
This is because of that I let the redefinition of cord in B and C, but I do not recommend you to do that kind of redefinition in 'real' codes ;-)
Lets take the B constructor:
B(){
A a;
a.display();
}
In it you create a completely separate object a of type A, and call display on it. That display call will be using the a object, not knowing anything about the B class or its totally separate cord member variable at all.
One possible way to solve this is to create a constructor of A that takes the value of cord as an argument, pass the "correct" value in the B constructor initializer list, and then call the display function on this object:
struct A{
A() = default;
explicit A(int c)
: cord(c)
{
}
display(){
cout<<cord<<endl;
}
int cord = 25;
};
struct B : A{
B()
: A(30)
{
display(); // Equivalent to this->display();
}
};
Of course, you need to do something similar for the C class (or structure).
Note that I removed the member variable cord from the B class. That's because if you declare a new member variable with the same name as a member variable in a base class, then you effectively create a completely new member variable that is unrelated to the one in the parent class. And for the simple example you show there's no need to "override" the member variable, as it already exists in all child-classes as well.
Can you please explain me why I receive error trying to access the members of the nested class from the derived class:
class Base
{
public:
static int A;
class inside_Base {public: static int B;};
};
int Base::A = 1;
int Base::inside_Base::B = 2;
class Derived : public Base {};
then in main I have:
Base * p;
p = new Derived();
when I try to print p->inside_Base::B I receive below error:
error: 'Base::inside_Base' is not a base of 'Derived'
Thanks.
As #V.Kravchenko said, you should not use static members through created objects. There is no variables polymorphism, only the functions one.
Usually you do not need to refer to inside_Base through Derived, because you lie that the Base::inside_Base is a nested class of Derived. But if you want it very much, you can typedef it:
class Derived : public Base
{
public:
typedef Base::inside_Base inside_Base;
};
In this case you can write Derived::inside_Base::B, for example (checked in MSVC 9.0). But, of course, it has no polymorphism as the class is defined statically in compile time.
What means p->A? Why not p->inside_Base::B?
p->A is equivalent to Base::A. It is C++ feature that allow you to use static variables as non-static. Don't know why it is needed.
var->Class::member says that you want a member symbol from class Class related to var instance. It is needed to resolve ambiguous symbols that may be used with var. For example:
class Base
{
public:
int x = {1};
};
class Derived
{
public:
int x = {2};
};
void main()
{
Derived var
std::cout << var.x << " " << var.Base::x;
}
Out will be 2 1. In second call we want to get exactly Base's member.
So, p->inside_Base::B says that you want a B from exactly class inside_Base related to p variable. But inside_Base is not a p's class and not a derived one. You can ask: why compiler doesn't scan nested classes? I think that because nobody needs it. It will complicate compilation and will not benefit as it doesn't resolve any ambiguousness.
I want to change a variable member of class B, in a method member of class A.
Example:
A.h:
class A
{
//several other things
void flagchange();
}
A.cpp:
void A::flagchange()
{
if (human) Bobj.flag=1;
}
I know that I need an object of class B, to change a variable member of B, but objects of B are not reachable in A. Is it possible by a pointer??
but objects of B are not reachable in A
If objects of class B are not reachable by class A there's no way you can modify them. Once you refactored your design, you should pass it as an argument to the function:
class A {
//several other things
void flagchange(B& obj) {
if (human)
obj.flag = 1;
}
};
I want to be able to toggle the flag from a method of class A for every object of B
You should declare your flag public variable as static in B:
class B {
public:
static int flag;
};
int B::flag = 0;
And then, from inside A:
class A {
//several other things
void flagchange() {
if (human)
B::flag = 1;
}
};
So say I have 3 classes: Base, A, and B.
Base is a base class for both class A and class B.
Base has a variable val that A and B can access.
How would I get it to work where I can set the val variable through class A, and it is reflected in class B?
For example:
I know this code below won't work because I am creating an OBJECT of the type a and b.
What I want to do is to simply have a and b share the same variable so that whenever a does something to it, it is reflected in b.
a aa;
b bb;
aa.SetVal(50000);
cout << aa.GetVal() << endl;
cout << bb.GetVal() << endl;
In the end I'd want both cout lines to print out 50000.
EDIT: The classes A and B will be doing different operations and just need to be able to access/change the val variable in base
You could make the member a static member of the base class, then all derived classes could access it, however any object of a derived that changes the static member would change it for every other object.
class Base
{
public:
int GetVal()
{
return val;
}
void SetVal( int newVal )
{
val = newVal;
}
private:
static int val;
};
// Need to instantiate the static variable somewhere
int Base::val = 0;
class A : public Base
{};
class B : public Base
{};
class Base {
static int value;
public:
virtual ~Base() { }
void setVal(const int& val) {
value = val;
}
int getVal() const {
return value;
}
};
int Base::value = 0;
class A : public Base {
};
class B : public Base {
};
#include <iostream>
int main() {
A a;
B b;
a.setVal(20);
std::cout << b.getVal(); // 20
}
That's a job for references, not for classes. Just have one class X and create a reference to the object:
X aa;
X& bb = aa;
aa.SetVal(50000);
std::cout << aa.GetVal() << std::endl;
std::cout << bb.GetVal() << std::endl;
The output will be:
50000
50000
Remember to always use the right tool for the job and keep things simple.
The main goal is that those two classes will be doing different things but will need to be able to access and share a single variable.
An idea to solve this is to extract the common variable in another class, namely S, which will be passed to A and B like this:
std::shared_ptr<S> s = new S();
A aa(s);
B bb(s)
Now, both aa and bb share the same S object and can modify it very easily. Notice that the constructor of both A and B should store the std::shared_ptr<S> as well:
class A { // and B
private:
std::shared_ptr<S> s;
public:
A(std::shared_ptr<S> as) : s(as) {}
};
The variable s will last as long as any of aa and bb is alive: when both aa and bb gets deallocated or go out of scope, the variable s will be deallocated as well.
If the type of the common variable should be on the stack, you can also just use references, but watch out for the lifetime of aa, bb and that variable:
int s = 0;
A aa(s);
B bb(s);
with:
class A { // and B
private:
int& s; // or any other type
public:
A(int& as) : s(as) {}
};
But as a general rule of thumb I'd avoid shared state between objects. Most of the time, depending on the context, you can refactor your code and get rid of the shared dependency.
If the shared value is static in the base class, then all instances of derived classes will see exactly that one base class member.
If the value is not static, then each instance of a class will have its own copy whether or not the value is in a base class.
Not sure I understand what you are trying to do. Do you want all instances of A and B to share the same value? if so, declare it as static in the base class.
if not, how do you want to choose which one will share the value?
Is there a way of initializing a static class member after main() has started ?
One way to do that is to replace the static member data which static member function.
Say you've this class:
class A
{
static B static_b; //static member data
};
//.cpp
B A::static_b; //definition (required)
So instead of that you can define your class as:
class A
{
static B static_b() //static member function!
{
static B b;
return b;
}
};
Note that it is not thread-safe, but you can make it thread-safe as well.
You can use a pointer for this object:
class SomeClass{
public:
static SomeOtherClass* p;
};
SomeOtherClass* SomeClass::p;
void main(){
SomeClass::p = new SomeOtherClass();
}