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
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;
}
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.
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;
}
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();
};
};
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.