Derived Get/Set Methods - c++

Imagine I have this code:
class A {
public:
void GetInt() { cout << number << endl; }
void SetInt(int n) { number = n; }
private:
int number = 0;
};
class B : public A {
public:
void GetInt() { cout << number << endl; }
private:
int number = 0;
};
int main() {
B b;
b.SetInt(5);
b.GetInt(); // Prints 0, needs to be 5
return 0;
}
Is there any way to make SetInt() changing B.number without implementing it in B? Imagine I have 500 derived classes from A, and they set their number in the same { number = n; }. Do I have to implement the same SetInt() method 500 times?

The simple way to get what you ask for is this:
class A {
public:
void GetInt() { cout << number << endl; }
void SetInt(int n) { number = n; }
private:
int number = 0;
};
class B : public A {
// don't hide methods inherited from A
// don't add members that are already present (as private member of A)
};
int main() {
B b;
b.SetInt(5);
b.GetInt(); // Prints 5
return 0;
}
Private members are inherited, they just cannot be accessed directly. Though as A does provide public accessors, B has acess to A::number via the setter from A.
PS A method called Get___ should actually return something, not just print the value on the screen.

No, 0 is the correct result. In your class B you create a whole new member B::number which is independent from A:::number. So when you run A::SetInt, that member function changes A::number and when you run B::GetInt, that function accesses A::number which was never set to 5.
Try not to have members in derived types that have the same name as a member in the base class. All it does is create confusion.

In case you really want each derived class to yield and handle its own value in terms of class hierachy separation - which I'd find at least questionable at all in terms of design and problem solution approach - you cannot avoid a minimum amount of code duplication for each derivation. At least you need the member access itself to be duplicated. There are some template/macro tricks to circumvent code explosions here (generic member instrusion), but since I really don't think, that this is what you want to achieve, I do not go into details for now.
Otherwise, idclev 463035818's answer is the way to go.

Related

C++ polymorphism: how to create derived class objects

I have an abstract base class called BaseStrategy. It contains one pure virtual function calculateEfficiency(). There are two classes ConvolutionStrategy and MaxPoolStrategy which derive from this base class and implement their own specific version of calculateEfficiency().
Here is some code:
class BaseStrategy {
public:
explicit BaseStrategy();
virtual ~BaseStrategy() = default;
private:
virtual double calculateEfficiency(mlir::Operation* op) = 0;
};
class ConvolutionStrategy : public BaseStrategy {
private:
double calculateEfficiency(mlir::Operation* op)
{
//some formula for convolution
return 1;
}
};
class MaxPoolStrategy : public BaseStrategy {
private:
double calculateEfficiency(mlir::Operation* op)
{
//some formula for MaxPool
return 1;
}
};
Now I have another class called StrategyAssigner. It has method calculateAllLayerEfficiencies() whose purpose is to iterate over all layers in a network. Depending on the type of layer there is a switch statement and should call the correct calculateEfficiency() depending on the layer type.
class StrategyAssigner final {
public:
explicit StrategyAssigner(){};
public:
void calculateAllLayerEfficiencies() {
// Logic to iterate over all layers in
// a network
switch (layerType) {
case Convolution:
// Call calculateEfficiency() for Convolution
break;
case MaxPool:
// Call calculateEfficiency() for MaxPool
break;
}
};
}
int main ()
{
StrategyAssigner assigner;
assigner.calculateAllLayerEfficiencies();
}
My question is, should I store references of objects Convolution and MaxPool in the class StrategyAssigner so that I can call the respective calculateEfficiency().
Or could you suggest a better way to call calculateEfficiency(). I don't really know how to create the objects (stupid as that sounds).
I can't make calculateEfficiency() static as I need them to be virtual so that each derived class can implemented its own formula.
If you included complete code I could give a more detailed answer, but you need to store BaseStrategy pointers that are initialized with derived class instances. Here's an example made from some of your code:
std::vector<std::unique_ptr<BaseStrategy>> strategies;
strategies.emplace_back(new ConvolutionStrategy);
strategies.emplace_back(new MaxPoolStrategy);
for (int i = 0; i < strategies.size(); ++i) {
std::unique_ptr<BaseStrategy>& pStrat = strategies[i];
pStrat->calculateEfficiency(...);
}
Note that this won't compile because I don't have enough details from the code you posted to make it so, but this shows how to exploit polymorphism in the way that you need.
Also, I used smart pointers for memory management; use these at your discretion.
You can indeed use runtime polymorphism here:
Declare ~BaseStrategy virtual (you are already doing it ;-)
If you are never going to instantiate a BaseStrategy, declare one of its methods as virtual pure, e.g. calculateEfficiency (you are already doing it as well!). I would make that method const, since it doesn't look it's going to modify the instance. And it will need to be public, because it will need to be accessed from StrategyAnalyser.
Declare calculateEfficiency as virtual and override in each of the subclasses. It could also be final if you don't want subclasses to override it.
I'd keep a std::vector of smart pointers to BaseStrategy at StrategyAssigner. You can use unique_ptrs if you think this class is not going to be sharing those pointers.
The key point now is that you create heap instances of the subclasses and assign them to a pointer of the base class.
class StrategyAssigner final {
public:
void addStrategy(std::unique_ptr<BaseStrategy> s) {
strategies_.push_back(std::move(s));
}
private:
std::vector<std::unique_ptr<BaseStrategy>> strategies_{};
};
int main()
{
StrategyAssigner assigner;
assigner.addStrategy(std::make_unique<ConvolutionStrategy>());
}
Then, when you call calculateEfficiency using any of those pointers to BaseStrategy, the runtime polymorphism will kick in and it will be the method for the subclass the one that will be actually called.
class ConvolutionStrategy : public BaseStrategy {
private:
virtual double calculateEfficiency() const override {
std::cout << "ConvolutionStrategy::calculateEfficiency()\n";
return 10;
}
};
class MaxPoolStrategy : public BaseStrategy {
private:
virtual double calculateEfficiency() const override {
std::cout << "MaxPoolStrategy::calculateEfficiency()\n";
return 20;
}
};
class StrategyAssigner final {
public:
void calculateAllLayerEfficiencies() {
auto sum = std::accumulate(std::cbegin(strategies_), std::cend(strategies_), 0,
[](auto total, const auto& strategy_up) {
return total + strategy_up->calculateEfficiency(); });
std::cout << "Sum of all efficiencies: " << sum << "\n";
};
};
int main()
{
StrategyAssigner assigner;
assigner.addStrategy(std::make_unique<ConvolutionStrategy>());
assigner.addStrategy(std::make_unique<MaxPoolStrategy>());
assigner.calculateAllLayerEfficiencies();
}
// Outputs:
//
// ConvolutionStrategy::calculateEfficiency()
// MaxPoolStrategy::calculateEfficiency()
// Sum of all efficiencies: 30
[Demo]

is there a "semi-pure" virtual function in c++?

Is there a way to write an abstract base class that looks like it's forcing an implementer to choose among a myriad of pure virtual functions?
The abstract base classes I'm writing define a mathematically tedious function, and request that the deriving code define only building block functions. The building block functions can be generalized to take on more arguments, though. For example, in the code below, it might "make sense" to allow another_derived::first() to take three arguments. The "mathematically tedious" part of this is the multiplication by 3. Unsurprisingly, it won't allow won't compile unless I comment out the creation of d2. I understand why.
One option is to create different base classes. One would request a single parameter function to be defined, and the other would request a two parameter function to be defined. However, there would be an enormous amount of code being copy and pasted between the two base class' definition of final_result(). This is why I'm asking, so I don't write WET code.
Another option would be to have one pure virtual function, but change the signature so that its implementation can do either of these things. I want to explore this, but I also don't want to start using fancier techniques so that it puts a barrier to entry on the type of people trying to inherit from these base classes. Ideally, if the writers of the base class could get away with barely knowing any c++, that would be great. Also, it would be ideal if the inheritors didn't even have to know about the existence of related classes they could be writing.
#include <iostream>
class base{
public:
virtual int first(int a) = 0;
int final_result(int a) {
return 3*first(a);
}
};
class derived : public base {
public:
int first(int a) {
return 2*a;
}
};
class another_derived : public base {
public:
int first(int a, int b) {
return a + b;
}
};
int main() {
derived d;
std::cout << d.final_result(1) << "\n";
//another_derived d2; // doesn't work
return 0;
}
Not sure it matches exactly what you want, but with CRTP, you might do something like:
template <typename Derived>
struct MulBy3
{
template <typename... Ts>
int final_result(Ts... args) { return 3 * static_cast<Derived&>(*this).first(args...); }
};
class derived : public MulBy3<derived> {
public:
int first(int a) { return 2*a; }
};
class another_derived : public MulBy3<another_derived > {
public:
int first(int a, int b) { return a + b; }
};
With usage similar to
int main() {
derived d;
std::cout << d.final_result(1) << "\n";
another_derived d2;
std::cout << d2.final_result(10, 4) << "\n";
}
Demo

Access default declared content from inherited class

I'm trying to make an inherited class access the self class default content.
The code is below (Note that array declared isn't the same size between parent and child class)
#include <iostream>
class A {
public:
int number[2] = {1,2};
A(){};
void show() {std::cout << "Number: " << number[0] << ", " << number[1] << "\n"; };
};
class B : public A {
public:
int number[3] = {5,6,7};
B() {};
// With this code below it works but I don't want to code the same function on every child class
//void show() {std::cout << "Number: " << number[0] << ", " << number[1] << "\n"; };
};
int main() {
A obj_a;
obj_a.show();
B obj_b;
obj_b.show();
}
Which outputs this:
Number: 1, 2
Number: 1, 2
Expected output should be:
Number: 1, 2
Number: 5, 6
Anyone can help?
Note: The code should be used on arduino, I used std::cout just for sharing to you.
EDIT:
I want to make an array of objects so it can be easily changed the size, and in other parts of the code, I can simply for loop of the array and do whatever is needed.
Also the purpose for subclasses is because I have different "numbers" and his sizes. For example, imagine a vehicle which is the super class, that has 2 child classes named "auto" and "moto", auto has int wheels[4] = {...} and moto int wheels[2] = {...}
A::number and B::number are two completely independent class members, that have nothing to do with each other.
A::show() only knows about members of A, and only knows about A::number. It doesn't know anything about B even if it's a superclass of an instance of B.
Your C++ textbook will explain what virtual functions are, and how to use them. The simplest solution is to add a virtual method in A, let's call it get_number, that returns an int *, and the get_number function simply returns number:
class A {
// ...
virtual int *get_number()
{
return number;
}
};
In B the virtual function gets overridden, and it returns a pointer to its own class's number.
class B {
// ...
int *get_number() override
{
return number;
}
};
Then, your show() method calls get_number() to get a pointer to the appropriate array. See your C++ textbook for a complete discussion of virtual class methods.
You are experiencing name hiding - name in inner scope shadows the same symbol name in outer scope. In your case B::number hides A::number.
C++ does not support "virtual" member variables, so you cannot redefine number. My suggestion is to not use inheritance if there should indeed be just one array. Because then B is not really an A.
Or at least you could generalize the A class to contain arbitrarly long array. There are multiple ways doing that:
std::vector A::number member with a constructor A(std::size_t n) accepting the size.
Make A a class template with template<std::size_t N> argument denoting the size, then you can use std::array<int,N> number; member variable.
Pass the array to the base class for ownership.
Another option is to make show virtual and override it in the derived class with custom printing, but then you will still be left with two arrays, which is a clear design flaw.

Changing an object from one derived class to another

I have a couple of classes that share a common base class, with the exception that they differ in the way their methods work. So in the example below, Adder and Multiplier are the same except for the way in which their calculation is performed.
Is there a way to change "a" to a Multiplier on the fly? Do I need to implement methods which convert derived classes to each other? e.g. something like
a = a.asMultiplier()?
As you can see in the code below I tried reinterpret_cast to a Multiplier, with no luck, it still acts like an Adder. (gcc OS X v4.2.1)
#include <iostream>
class Base {
protected:
int a,b;
public:
Base(int a, int b) {
this->a = a;
this->b = b;
}
virtual ~Base() { }
virtual int calculate() = 0;
};
class Adder : public Base {
public:
Adder(int a, int b) : Base(a, b) {
}
int calculate() {
return this->a + this->b;
}
};
class Multiplier : public Base {
public:
Multiplier(int a, int b) : Base(a, b) {
}
int calculate() {
return this->a * this->b;
}
};
int main() {
Base* a = new Adder(3,4);
Base* m = new Multiplier(3,4);
std::cout << "Adder gives " << a->calculate() << std::endl;
std::cout << "Multiplier gives " << m->calculate() << std::endl;
a = reinterpret_cast<Multiplier*>(a);
std::cout << "Now adder gives " << a->calculate() << std::endl;
delete a;
delete m;
return 0;
}
The best thing that comes up to me to solve this, is implementing a copy constructor, taking the base class:
class Multiplier : public Base {
public:
Multiplier(int a, int b) : Base(a, b) {
}
explicit Multiplier(const Base& iBase) : Base(iBase.a, iBase.b) {
}
int calculate() {
return this->a * this->b;
}
};
But since I am not the most advanced c++ developer here, it might not be correct or other people might have a better idea, just trying :)
I would propose to decouple the object's data from its operations. This way you can easily construct one object from another, overtaking the data. So your "conversion" will look like this: Multiplier m = new Multiplier(a);
Doing it the way you are asking for is impossible in C++.
This seems to me that you would need utility classes that operate on data: Change your base class to a Data class whose purpose is only to store the data and pass the data explicitly to the Adder, Multiplier etc. classes.
You can still use inheritance in the utility classes if it makes sense after the above refactoring: in this case base would also operate on a Data object, instead of being the Data itself
It is probably a good idea to change your design. In general I would say that it is a good idea to used inheritance when there is some kind of commonality shared by base and derived classes, not only in terms of data, but in terms of behaviour. Whilst not being very helpful advice directly I would suggest maybe reading some books on object oriented design principles. Trying to cast types in the way you are really makes no sense.

How to access private data members outside the class without making "friend"s? [duplicate]

This question already has answers here:
Can I access private members from outside the class without using friends?
(27 answers)
Closed 6 years ago.
I have a class A as mentioned below:-
class A{
int iData;
};
I neither want to create member function nor inherit the above class A nor change the specifier of iData.
My doubts:-
How to access iData of an object say obj1 which is an instance of class A?
How to change or manipulate the iData of an object obj1?
Note: Don't use friend.
Here's a way, not recommended though
class Weak {
private:
string name;
public:
void setName(const string& name) {
this->name = name;
}
string getName()const {
return this->name;
}
};
struct Hacker {
string name;
};
int main(int argc, char** argv) {
Weak w;
w.setName("Jon");
cout << w.getName() << endl;
Hacker *hackit = reinterpret_cast<Hacker *>(&w);
hackit->name = "Jack";
cout << w.getName() << endl;
}
Bad idea, don't do it ever - but here it is how it can be done:
int main()
{
A aObj;
int* ptr;
ptr = (int*)&aObj;
// MODIFY!
*ptr = 100;
}
You can't. That member is private, it's not visible outside the class. That's the whole point of the public/protected/private modifiers.
(You could probably use dirty pointer tricks though, but my guess is that you'd enter undefined behavior territory pretty fast.)
EDIT:
Just saw you edited the question to say that you don't want to use friend.
Then the answer is:
NO you can't, atleast not in a portable way approved by the C++ standard.
The later part of the Answer, was previous to the Q edit & I leave it here for benefit of >those who would want to understand a few concepts & not just looking an Answer to the >Question.
If you have members under a Private access specifier then those members are only accessible from within the class. No outside Access is allowed.
An Source Code Example:
class MyClass
{
private:
int c;
public:
void doSomething()
{
c = 10; //Allowed
}
};
int main()
{
MyClass obj;
obj.c = 30; //Not Allowed, gives compiler error
obj.doSomething(); //Allowed
}
A Workaround: friend to rescue
To access the private member, you can declare a function/class as friend of that particular class, and then the member will be accessible inside that function or class object without access specifier check.
Modified Code Sample:
class MyClass
{
private:
int c;
public:
void doSomething()
{
c = 10; //Allowed
}
friend void MytrustedFriend();
};
void MytrustedFriend()
{
MyClass obj;
obj.c = 10; //Allowed
}
int main()
{
MyClass obj;
obj.c = 30; //Not Allowed, gives compiler error
obj.doSomething(); //Allowed
//Call the friend function
MytrustedFriend();
return 0;
}
http://bloglitb.blogspot.com/2010/07/access-to-private-members-thats-easy.html
this guy's blog shows you how to do it using templates. With some modifications, you can adapt this method to access a private data member, although I found it tricky despite having 10+ years experience.
I wanted to point out like everyone else, that there is an extremely few number of cases where doing this is legitimate. However, I want to point out one: I was writing unit tests for a software suite. A federal regulatory agency requires every single line of code to be exercised and tested, without modifying the original code. Due to (IMHO) poor design, a static constant was in the 'private' section, but I needed to use it in the unit test. So the method seemed to me like the best way to do it.
I'm sure the way could be simplified, and I'm sure there are other ways. I'm not posting this for the OP, since it's been 5 months, but hopefully this will be useful to some future googler.
In C++, almost everything is possible! If you have no way to get private data, then you have to hack. Do it only for testing!
class A {
int iData;
};
int main ()
{
A a;
struct ATwin { int pubData; }; // define a twin class with public members
reinterpret_cast<ATwin*>( &a )->pubData = 42; // set or get value
return 0;
}
There's no legitimate way you can do it.
Start making friends of class A. e.g.
void foo ();
class A{
int iData;
friend void foo ();
};
Edit:
If you can't change class A body then A::iData is not accessible with the given conditions in your question.
iData is a private member of the class. Now, the word private have a very definite meaning, in C++ as well as in real life. It means you can't touch it. It's not a recommendation, it's the law. If you don't change the class declaration, you are not allowed to manipulate that member in any way, shape or form.
It's possible to access the private data of class directly in main and other's function...
here is a small code...
class GIFT
{
int i,j,k;
public:
void Fun()
{
cout<< i<<" "<< j<<" "<< k;
}
};
int main()
{
GIFT *obj=new GIFT(); // the value of i,j,k is 0
int *ptr=(int *)obj;
*ptr=10;
cout<<*ptr; // you also print value of I
ptr++;
*ptr=15;
cout<<*ptr; // you also print value of J
ptr++;
*ptr=20;
cout<<*ptr; // you also print value of K
obj->Fun();
}
friend is your friend.
class A{
friend void foo(A arg);
int iData;
};
void foo(A arg){
// can access a.iData here
}
If you're doing this regularly you should probably reconsider your design though.
access private members outside class ....only for study purpose ....
This program accepts all the below conditions
"I dont want to create member function for above class A. And also i dont want to inherit the above class A. I dont want to change the specifier of iData."
//here member function is used only to input and output the private values ...
//void hack() is defined outside the class...
//GEEK MODE....;)
#include<iostream.h>
#include<conio.h>
class A
{
private :int iData,x;
public: void get() //enter the values
{cout<<"Enter iData : ";
cin>>iData;cout<<"Enter x : ";cin>>x;}
void put() //displaying values
{cout<<endl<<"sum = "<<iData+x;}
};
void hack(); //hacking function
void main()
{A obj;clrscr();
obj.get();obj.put();hack();obj.put();getch();
}
void hack() //hack begins
{int hck,*ptr=&hck;
cout<<endl<<"Enter value of private data (iData or x) : ";
cin>>hck; //enter the value assigned for iData or x
for(int i=0;i<5;i++)
{ptr++;
if(*ptr==hck)
{cout<<"Private data hacked...!!!\nChange the value : ";
cin>>*ptr;cout<<hck<<" Is chaged to : "<<*ptr;
return;}
}cout<<"Sorry value not found.....";
}