c++ accessing variable from nested class method - c++

How can I access class attribute from its nested class method?
class Class1
{
public:
int attribute;
void Method1() {
class Class2
{
public:
void Method2() {
//here I need to access attribute from Class1
}
};
}
};

Following is one way of doing it with minor changes to OP's code.
#include <cassert>
class Class1
{
public:
Class1( int attribute ) : attribute_( attribute ) {
}
void Method1() {
class Class2
{
public:
Class2( Class1 * parent ) : parent_( parent ) {
}
int parentAttribute() const {
return parent_->attribute_;
}
private:
Class1 * parent_;
};
Class2 c2( this );
assert( c2.parentAttribute() == attribute_ );
}
private:
int attribute_;
};
int main() {
Class1 c1( 42 );;
c1.Method1();
}
The code is also posted at http://codepad.org/MUF3a8jL

You can pass this to the inner class. For example:
class Class1
{
public:
Class1() : class2(this) {
}
int attribute;
void Method1() {
};
class Class2
{
Class1 *parent;
public:
Class2(Class1 *parent) : parent(parent) {
}
void Method2() {
// parent->attribute
}
} class2;
};

Related

Can you copy Derived Class objects from one std::vector<std::unique_ptr<BaseClass>> to another std::vector<std::unique_ptr<BaseClass>>?

I have two vectors. I register derived classes in one vector, then want to make copies and copy them over to the other vector. I am trying to do this to avoid base class slicing, but be able to have "templates" of classes that I use to spawn new objects that I can mutate from those.
How do I clone an object pointed to by unique_ptr and have a new unique_ptr that I can store in a vector?
The idea shown below is that I could have multiple copies of the class in active, while still having the original object in available. Or, is there a better architecture for trying to make copies of a derived class for storage?
#include <iostream>
#include <memory>
#include <vector>
class BaseClass {
virtual void doSomething(){}
};
class DerivedClass1: public BaseClass {
public:
float myVar1;
void doSomething() override { std::cout << "1"; }
};
class DerivedClass2: public BaseClass {
public:
int myVar2;
void doSomething() override { std::cout << "2"; }
};
std::vector<std::unique_ptr<BaseClass>> available;
std::vector<std::unique_ptr<BaseClass>> active;
void registerClass( std::unique_ptr<BaseClass> newAvailable ) {
available.push_back(std::move(newAvailable));
}
void makeActive() {
for( auto &toMakeActive : available ) {
// todo: ?? // active.push_back( available->clone() );
}
}
int main() {
std::unique_ptr<DerivedClass1> derived1 = std::make_unique<DerivedClass1>();
std::unique_ptr<DerivedClass2> derived2 = std::make_unique<DerivedClass2>();
registerClass( std::move( derived1 ) );
registerClass( std::move( derived2 ) );
makeActive();
makeActive();
return 0;
}
How do I clone an object pointed to by unique_ptr and have a new unique_ptr that I can store in a vector?
C++ has no facility to handle this automatically, you have to implement it manually in each derived class, eg:
#include <iostream>
#include <memory>
#include <vector>
class BaseClass {
virtual void doSomething(){}
virtual std::unique_ptr<BaseClass> clone() = 0;
};
class DerivedClass1: public BaseClass {
public:
float myVar1;
void doSomething() override { std::cout << "1"; }
std::unique_ptr<BaseClass> clone() override { return std::make_unique<DerivedClass1>(*this); }
};
class DerivedClass2: public BaseClass {
public:
int myVar2;
void doSomething() override { std::cout << "2"; }
std::unique_ptr<BaseClass> clone() override { return std::make_unique<DerivedClass2>(*this); }
};
std::vector<std::unique_ptr<BaseClass>> available;
std::vector<std::unique_ptr<BaseClass>> active;
void registerClass( std::unique_ptr<BaseClass> newAvailable ) {
available.push_back(std::move(newAvailable));
}
/* alternatively:
template<class T>
void registerClass() {
available.push_back(std::make_unique<T>());
}
*/
void makeActive() {
for( auto &toMakeActive : available ) {
active.push_back( available->clone() );
}
}
int main() {
registerClass( std::make_unique<DerivedClass1>() );
registerClass( std::make_unique<DerivedClass2>() );
/* alternatively:
registerClass<DerivedClass1>();
registerClass<DerivedClass2>();
*/
makeActive();
makeActive();
return 0;
}

C++ : function pointer and class members

I have a problem with the following piece of code that can't even compile.
The problem is on the line
class2_ = new Class2(myFunction);
In fact, I don't now how to reference myFunction, I have also tried class2_ = new Class2(&Class3::myFunction); but the compiler still complains :(
2 constraints:
The function myFunction can't be declared as static
This code will be used in a Arduino base project, I can't use boost::bind
Could you please help me ?
Thanks.
class Class2 {
typedef void(*MyFunction) (int what);
MyFunction fn_;
public:
Class2(MyFunction fn) : fn_(fn) {}
void invoke(int val) {
fn_(val);
}
};
class Class3 {
Class2* class2_;
public:
Class3() {
class2_ = new Class2(myFunction);
class2_->invoke(12);
}
void myFunction(int what) {
// Do some work
}
};
void test2() {
Class3 instance3;
}
How about using an interface for that:
class ClassWithFunction {
public:
virtual void myFunction(int what) = 0;
}
class Class2 {
ClassWithFunction* fn_;
public:
Class2(MyFunction* fn) : fn_(fn) {}
void invoke(int val) {
fn_->myFunction(val);
}
};
class Class3 : ClassWithFunction {
Class2* class2_;
public:
Class3() {
class2_ = new Class2(this);
class2_->invoke(12);
}
void myFunction(int what) {
// Do some work
}
};
You need to use pointer to member function.
class Class3;
class Class2 {
typedef void(Class3::*MyFunction) (int);
MyFunction fn_;
public:
Class2(MyFunction fn) : fn_(fn) {}
void invoke(Class3 *p, int val) {
(p->*fn_)(val);
}
};
class Class3 {
Class2* class2_;
public:
Class3() {
class2_ = new Class2(&Class3::myFunction);
class2_->invoke(this, 12);
}
void myFunction(int what) {
// Do some work
}
};
If you want that Class2 accepts any callable object with signature void(int), then class template, function wrapper, lambda expression etc. will help.

Baseclass method is called instead of the one in the subclass

I've created a BaseClass and two subclasses: SubOne and SubTwo. After that I created a collection called MyCollection which stores the instances in a vector.
Both the base class, and the subclasses have the method getString. Base class returns with base, and the subclasses with sub1 and sub2.
I don't get any warning or error during the compilation. But for some reason, if I try to iterate over the vector, the subclasses return "base"
#include <iostream>
#include <vector>
class BaseClass {
public:
BaseClass() {}
std::string getString() {
return "base";
}
};
class SubOne : public BaseClass {
public:
SubOne() : BaseClass() {}
std::string getString() {
return "sub1";
}
};
class SubTwo : public BaseClass {
public:
SubTwo() : BaseClass() {}
std::string getString() {
return "sub2";
}
};
class MyCollection {
private:
std::vector<BaseClass> instances;
public:
MyCollection() {}
void add(BaseClass & ins) {
instances.push_back(ins);
}
std::string printString() {
for(std::vector<BaseClass>::iterator it = instances.begin() ; it != instances.end(); ++it) {
std::cout << it->getString() << std::endl;
}
}
};
int main() {
MyCollection *coll = new MyCollection();
SubOne* s1 = new SubOne();
SubTwo* s2 = new SubTwo();
coll->add(*s1);
coll->add(*s2);
coll->printString();
return 0;
}
You forgot to use keyword virtual. Also translate to pointers (credit goes to Captain Giraffe).
See code below:
#include <iostream>
#include <vector>
class BaseClass {
public:
BaseClass() {}
virtual std::string getString() { // BINGO _!_!_!_!
return "base";
}
};
class SubOne : public BaseClass {
public:
SubOne() : BaseClass() {}
std::string getString() {
return "sub1";
}
};
class SubTwo : public BaseClass {
public:
SubTwo() : BaseClass() {}
std::string getString() {
return "sub2";
}
};
class MyCollection {
private:
std::vector<BaseClass*> instances;
public:
MyCollection() {}
void add(BaseClass* ins) {
instances.push_back(ins);
}
std::string printString() {
for(std::vector<BaseClass*>::iterator it = instances.begin() ; it != instances.end(); ++it) {
std::cout << (*it)->getString() << std::endl;
}
}
};
int main() {
MyCollection *coll = new MyCollection();
SubOne* s1 = new SubOne();
SubTwo* s2 = new SubTwo();
coll->add(s1);
coll->add(s2);
coll->printString();
return 0;
}

How to get rid of duplicate code in derived classes?

I have a class hierarchy like:
class A {
list<A*> children;
public:
void update() {
do_something();
update_current();
for(auto child : children)
children->update();
}
protected:
virtual void update_current() {};
};
class B : public A {
protected:
void update_current() override {
do_something_important();
};
};
class C1 : public B {
protected:
void update_current() override {
B::update_current();
do_something_very_important();
};
};
class C2 : public B {
protected:
void update_current() override {
B::update_current();
do_something_very_important_2();
};
};
int main() {
A* a = new A();
//fill a's childred list somehow
while(come_condition) {
//some code
a.update();
//something else
}
return 0;
}
The question is: how can I remove duplicate B::update_current(); calls from derived classes without changing program's behaviour? Is it possible or are there no solutions except calling base class functions manually? Thank you.
You could make B's children override a different function:
class B : public A {
protected:
void update_current() override final {
do_something_important();
do_something_important_later();
};
virtual void do_something_important_later() = 0;
};
With:
class C2 : public B {
protected:
void do_something_important_later() override {
do_something_very_important_2();
};
};

Can i call VFunc from outside of the object?

I like the results of this code but i was curious, is it possible to call B::VFunc() from main()? I know writing B::VFunc(); inside of C will call it but is it possible to call the function from outside of the object?
http://ideone.com/Dg8aa
#include <cstdio>
class I { public: virtual void VFunc()=0; };
class B : public I { public: void VFunc() { printf("B\n"); } };
class C : public B { public: void VFunc() { printf("C\n"); } };
int main(){
C v;
B&i = v;
i.VFunc();
}
output:
C
This will do it:
#include <cstdio>
class I { public: virtual void VFunc()=0; };
class B : public I { public: void VFunc() { printf("B\n"); } };
class C : public B { public: void VFunc() { printf("C\n"); } };
int main(){
C v;
B&i = v;
i.B::VFunc();
}
Example: http://ideone.com/MfyYJ
You can resort to slicing:
C v;
B i = (B)v;
http://ideone.com/YVI2T
The dynamic type of v is lost, so B::VFunc is called.