Access the protected variable from a nested class to the enclosing class - c++

class A
{
public:
class B
{
public:
int changevar (int b)
{
a = b; // 5 should go in "a"
}
int get()
{
return a;
}
protected:
int a = 0; // value initialized here
};
private:
int usechangedvar(B& hello);
};
int A::usechangedvar(B& hello)
{
int final = hello.get(); // 5 should go in "final"
return final;
}
int main()
{
A::B hi;
hi.changevar(5);
A obj;
obj.usechangedvar(hi);
}
This code will not compile because it will say that I am trying to access the private method.
Regardless, I am not sure what is the correct way of doing this but finally what I want is:
Under class B there is a protected variable whose value is changed by the public method called "changevar". Once the value is changed, I need to store that value in the variable "final" inside the private method called "usechangedvar".
Note: I do not want to change the variable "a" from protected to something else.
Edit: I am open to suggestions where class B is not a nested class. I can keep it outside meaning A and B are not within one another
EDITED:
#include <stdio.h>
#include <iostream>
#include <stdint.h>
class A
{
public:
class B
{
public:
int changevar (int b) ------------- This method is called by application code(user) and whatever value user gives here should be the changed value
{
a = b; // 5 should go in "a"
}
// int get()
// {
// return a;
// }
protected:
int a = 0; // value initialized here. This could be anything private/protected
};
class C : public class B
{
};
private:
int usechangedvar();
};
int A::usechangedvar()
{
// 5 should come here which was inputted by user.
}
int main()
{
//1) I instantiate class C by doing
A::C objC;
objC.changevar(5);
// Whole purpose is to take 5 from user and then use it eventually in "usechangedvar" method.
}

Here is your problem reproduced with unrelated details eliminated:
class A
{
private:
int usechangedvar(int hello) { return hello; }
};
int main()
{
A obj;
obj.usechangedvar(5); //compile error, usechangedvar is private
}
Problem in your code is completely unrelated to class B as you can see here - you cannot call A::usechangedvar() from main() as it is private method of class A.
If you just need to check if your method usechangedvar() works you may add public method to A for example test(), call usechangedvar() from it and probably print the result. Then you can call obj.test() from main() and see if it works. You may want to remove that method test() if necessary after test is done.

Related

Is there any way that data can be inherited from one class to another?

I am trying to learn object oriented programming, and I got stuck at a problem. I have two class A and B. I am passing command line argument into class A, which then performs some computations and forms a 2d vector. (lets call the vector data)
I want class B to inherit class A.
So I was wondering is there any way, in which when default constructor of class B is called and it prints the contents of 2d vector data.
Sample code of what I have tried
class A
{
public:
vector<vector<string>>data;
fstream file;
string word, filename;
A()
{
}
A(string fileOpen)
{
file.open(fileOpen);
while (file >> word)
{
vector<string>rowTemp={word};
data.push_back(rowTemp);
}
}
vector<vector<string>> getVector()
{
return data;
}
};
class B:A
{
public:
B()
{
for(auto i:data)
{
for(auto j:i)
{
cout<<j<<' ';
}
cout<<endl;
}
}
};
int main(int argc, char* argv[]){
fstream file;
string word, filename;
file.open(argv[1]);
string fileOpen=argv[1];
A s(fileOpen);
B c;
return 0;
}
I basically want class B to have access 2d vector data so that I can perform further computations on it, while logic of computation remains inside class B.
Is there a way to do this?
Also, as you can see inside class A the default constructor is empty. But it is needed because without it, I received an error that default constructor of class B cannot be called. Is there a better way to write this? As having an empty default constructor looks bad.
You seem to misunderstand how inheritance works, it is just not clear what you expected. The thing is: Members of a base class are always inherited. Their access can be limited, but they are still there.
Consider this simplified example:
#include <iostream>
class A {
public:
int data = 42;
A() = default;
A(int value) : data(value) {}
int getData() { return data; }
};
class B : A {
public:
B() {
std::cout << A::data; // ok
std::cout << A::getData(); // ok
}
};
int main(){
B c;
//std::cout << c.data; // error: data is private!
}
Output is:
4242
Because B does inherit the data member from A. Inside B you can access data either directly or via getData because both are public in A. However, because B inherits privately from A (thats the default inheritance for classes defined via class) you cannot directly access either data nor getData in main.
Furtermore, when you write:
A s(fileOpen);
B c;
Then s and c are two completely unrelated objects. I suppose you rather want:
B c{fileOpen};
and call As constructor from the constructor of B:
B(const std::string& filename) : A(filename) {
// now you can access A::data
// which has been initialized in
// constructor of A
}

Calling a method inside a method of a different class C++

In my code, I have two classes. The first class has a private variable x. I'm trying to change its value by calling a method defined in a second class - setClass1X(). This method takes two parameters, the value that I want to set x to and an object of type class1. This method should call another method setX() of an object given as a parameter and pass it the value that i want to set x to. Then that method setX(), defined in the first class should set the value of x for that particular object. At the end program calls a function getX() from the first class and prints its return value. I always get 0 as an output because that is what constructor sets the value of x to, meaning that this approach does not work. Can you spot a mistake or tell my why this approach does not work. Thanks!
#include<iostream>
using namespace std;
class class1
{
private:
int x;
public:
class1()
{
x=0;
}
int getX()
{
return x;
}
void setX(int a)
{
x=a;
}
};
class class2
{
public:
void setClass1X(int n, class1 c)
{
c.setX(n);
}
};
int main()
{
class1 c1;
class2 c2;
c2.setClass1X(5, c1);
cout << c1.getX();
return 0;
}
As #MikeCAT has already pointed out a copy of class1 being pass and the changes made to the copy doesnt reflect into the original instance. So the solution is to pass the instance by reference.
However classes should be dependned on each other at the class level rather than at method level to mark clear dependnecy; unless you there is specific reason for not doing this.
class class2
{
private:
class1& c1;
public:
class2(class1& c)
: c1(c)
{
}
void setClass1X(int n)
{
c1.setX(n);
}
};
int main()
{
class1 c1;
class2 c2(c1);
c2.setClass1X(5);
cout << c1.getX();
return 0;
}
In Your setClass1X function, a copy of an object is passed to c1, so modification to that won't affect caller.
To have your functions modify what is passed, you should use references.
void setClass1X(int n, class1& c) // add "&"
{
c.setX(n);
}

c++ access main objects from other file

I wonder how it is possible to access an object that was created in the main function from another class.
main.cpp
#include"ClassA.h";
#include"ClassB.h";
int main()
{
ClassA objectA;
return 0;
}
ClassA.h
#pragma once
class ClassA
{
public:
ClassA():_privateVar(100)
{};
~ClassA()
{};
//Getters
float getPrivateVarA(){ return _privateVarA; };
//Setters
void setPrivateVarA(float privateVarA){ _privateVarA = privateVarA; };
private:
//Just a value
float _privateVarA;
};
ClassB.h
#pragma once
class ClassB
{
public:
ClassB():_privateVarB(50)
{ };
~ClassB()
{ };
//This is what i´m trying to achieve: Acces objectA
// like this: objectA.getPrivateVarA(); or objectA.setPrivateVarA;
int getPrivateVarB(){return _privateVarB;};
private:
int _privateVarB;
};
I've been all week searching for an answer to this and found nothing...
If anyone knows of some books or have any information on how I can get there would be grateful.
Thank you.
You placed your question in the middle of the ClassB declaration. You can't execute code there. Whatever you do must be done from within a function.
A function in ClassB can be defined so that it accepts a reference or pointer to a ClassA. Then that reference can be used to call getPrivateVarA().
In other words, if class B needs to access a class A then it is up to your code to initialize B with the required reference. This can be done when creating the B object, or when calling a method of the B object.
objectA has function-local scope within main(). By definition, objects can be directly accessed only within their visible scope. That's what C++ is all about.
Of course, if you pass a reference or a pointer to this object, to some other function, that other function can access the instantiated object indirectly, via the pointer or the reference.
I can't say with 100% certainty that you can't, but you definitely should not be doing that. If you want to use an object created in a different scope then you need to pass it into the scope you want to access it from either by value, reference or via a pointer.
First Class A:
class A {
public:
ClassA() : _privateVar(100) {}
~ClassA() {}
float getPrivateVarA() { return _privateVar; }
void setPrivateVarA(float val) { _privateVar = val; }
private:
float _privateVar;
};
First Class B:
class B {
public:
ClassB() : _privateVar(50) {}
~ClassB() {}
// by copy
float getPrivateVarB_byCopy(ClassA a) {
return _privateVar + a.getPrivateVarA();
}
// by reference
float getPrivateVarB_byRef(ClassA &a) {
return _privateVar + a.getPrivateVarA();
}
// by pointer
float getPrivateVarB_byPointer(ClassA *a) {
return _privateVar + a->getPrivateVarA();
}
float setPrivateVarB(float val) { _privateVar = val; }
private:
float _privateVar;
};
Now for main.
int main(void) {
ClassB b;
ClassA a; // for copy and ref
ClassA *a2 = new ClassA(); // for pointer
b.getPrivateVarB_byCopy(a); // => 150
b.getPrivateVarB_byRef(a); // => 150
b.getPrivateVarB_byPointer(a2); // => 150
delete a2; // clean up pointer
return 0;
}
Although your example this type of access is really not a good idea, not sure why you'd want to go about doing things this way.

How access class variables in c++

Is it possible in c++ to access class variables in other classes without creating an object. I have tried to use static, but the other class doesnt recognize my variable.
I have 3 classes. In two of those the sae variables should be used. In the third class I am changing the values. Would be grateful if you could help. Maybe youve got an example.
class Myclass
{
public:
static int i;
};
int Myclass::i = 10;
class YourClass
{
public:
void doSomething()
{
Myclass::i = 10; //This is how you access static member variables
}
};
int main()
{
YourClass obj;
obj.doSomething();
return 0;
}
static is the right keyword here:
class A {
public:
static int i; // <-- this is a class variable
};
class B {
public:
void f() { A::i = 3; } // <-- this is how you access class variables
};
They only potential problem I can think of is that
You made the class variable protected or private, thus rendering it inaccessible from other code.
You forgot to specify the full scope of the class variable (with A:: in this example).
I think the Singleton Pattern would help, but I'm no big fan of it. A lot better design would be to have one class take ownership of the object, and pass references to this object to the other classes.
yes you can bro, try this
struct car{
string model;
string paint;
int price;
};
int main(){
// creates an object of the class car
car BMW;
// assign the values
bmw.model = "m sports";
bmw.paint ="red";
bmw.price = 24000;
}

Instantiating objects and object members

For some reason the following doesn't crash like my program does, but I'm pretty sure it's similar in design. For one, the output's not correct. It outputs something similar to:
0x537ff4 5471612
While the main program outputs (nil) for the pointer address.
The key to the problem might be display_ in Drv.
Here's the code:
#include <iostream>
#include "debug.h"
class LCDText {
public:
int rows_;
LCDText() { rows_ = 10; };
};
class Generic {
LCDText *lcdText_;
public:
Generic(LCDText *lcdText) { lcdText_ = lcdText; };
void Setup() {
Error("%p %d", lcdText_, lcdText_->rows_);
}
};
class Display : public LCDText {
Generic *visitor_;
public:
Display(Generic *visitor) { visitor_ = visitor; };
};
class Drv : public Generic {
Display *display_;
public:
Drv() : Generic((LCDText *)display_) {
display_ = new Display((Generic *)this);
};
~Drv() { delete display_; };
};
int main()
{
Drv drv;
drv.Setup();
return 0;
}
This code:
Drv() : Generic((LCDText *)display_) {
display_ = new Display((Generic *)this);
};
first runs the parent class's ctor, with a yet-uninitialized value of display_, then independently sets display_, but, too late to change the parent class. So the pointer held by the parent class will never be set correctly. I guess you need to add a protected setter method (or make the parent-class-held pointer member itself protected).
Your Drv constructor passes the garbage, uninitialized value of Drv::display_ to Generic before initializing it in the constructor body. You can do a couple of things here, my preferred would be:
class Drv : public Generic {
Display* display() { return (Display*)lcdText_; }
public:
Drv() : Generic(new Display(this)) {}
}
Because it doesn't result in a duplicate field, but you can also have an abstract getLcdText() in Generic, which could be better if you are already using virtual methods.
In the constructor for Drv, when you first call the constructor for Generic display_ is still uninitialized. You don't new the pointer until later.