So I have a class like
class mySafeData
{
public:
void Set( int i )
{
myMutex.lock();
myData = i;
myMutex.unlock();
}
void Get( int& i)
{
myMutex.lock();
i = myData;
myMutex.unlock();
}
private:
int myData;
boost::mutex myMutex;
};
its instance is running. Lets call instance A. I want to create a new class that would take as a start up argument some kind of link to Getter from A and would be capable to somehow save link to thet getter for calling it inside its private methods vhen needed. how to do such thing?
Sounds like you want something like this:
class myOtherData
{
public:
myOtherData(mySafeData& dataSource) :
myDataSource(&dataSource)
{}
private:
// note that if you take the advice in the comments,
// you don't need this wrapper function at all,
// it's simple just to call myDataSource.Get()
int GetData()
{
int result;
myDataSource.Get(result);
return result;
}
mySafeData* myDataSource;
};
mySafeData a;
myOtherData b(a);
// b uses a as its data source (make sure it lives as long!)
I'm not sure what you mean by linc/link. Are you asking for anything more than this pattern?
class Foo {
public:
Foo(mySafeData& d) : data(d) {}
int someFunction() {
int i;
data.get(i);
return i;
}
private:
mySafeData& data;
};
...
Foo f(a);
What's wrong with pointers? Smart, Shared, Scoped... I'll use standard pointers for now.
class B
{
public:
B(mySafeData* ptr) // constructor takes a memory pointer as parameter
:SafeData_ptr(ptr)
{
SafeData_ptr->foo(); // call public function from class A
}
~B() // destructor
{
}
private:
mySafeData* SafeData_ptr; // will hold the mem address of instance A when
// this class is initialized
};
Later on your code, when you have instance A ready, you would do something like this:
B b_demo(&A); // &A passes the memory address of the instantiated object
// and A::foo() will be automatically called when B is constructed.
This is probably not the smartest way to do it, but I think it illustrates the idea.
Related
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.
Is there any way in C++ to create class within a function, and then prevent it from destructing?
like
class someclass {
public:
int x;
someclass() { x = 0; };
}
someclass::x;
and then somewhere
someclass * somefunction()
{
someclass somecl ();
return &somecl;
}
So we call function 'somefunction' and get pointer to class for later using. I need it to exist as long as program runs/it destructed by other function. Is there any way to do it without storing it inside arrays or vectors?
I'm not sure if what you're looking for is a way to define an object once and only once, returning a pointer to the same object each time, or to create a factory function that returns the a newly constructed object each time. If it's the second, look at previous answers. If it's the first, check out static variables. As an example, you could write
someclass * somefunction()
{
static someclass somecl ();
return &somecl;
}
This ensures that somecl is only defined once, when the function is initially run and that it will be alive until your program exits. (For a more precise description of the order of cleanup for static variables, see here.)
Yes, you have to allocate the memory on the heap and then delete the memory when you are done.
someclass * somefunction()
{
return new someclass();
}
int main()
{
someclass * myclass = somefunction();
// do stuff with myclass
delete myclass;
return 0;
}
someclass * somefunction()
{
return new somecl ();
}
You were very close :)
You could create it on the heap rather than the stack:
someclass * somefunction()
{
return new someclass();
}
You may also want to consider returning it in a smart pointer, to explicitly transfer ownership and control its lifetime.
I'm not exactly sure what you are driving at, I can imagine two different use cases where you would want to make a class indestructible.
Case 1: Singleton
The idiomatic way to do this, is to use a static instance of the class that's declared within an accessor function:
class Foo {
public:
static Foo& globalFoo();
private:
Foo() {};
~Foo() {};
};
Foo& Foo::globalFoo() {
static Foo myFoo;
return myFoo;
}
int main() {
Foo& myFoo = Foo::globalFoo();
}
That way, it is impossible for other code to either construct or destruct any instance of Foo, it can only use the one instance that's provided by the globalFoo() function.
Case 2: Wrapped allocation/deallocation
If you just want to force allocation/deallocation to happen via certain static functions, you only need to make both the constructor and the destructor private (just as in the singleton case), and add static functions to the interface for allocation/deallocation:
class Foo {
public:
static Foo* makeFoo();
static void destroyFoo(Foo* aFoo);
private:
Foo() {};
~Foo() {};
};
Foo* Foo::makeFoo() {
return new Foo();
}
void Foo::destroyFoo(Foo* aFoo) {
delete aFoo;
}
int main() {
Foo* myFoo = Foo::makeFoo();
Foo::destroyFoo(myFoo);
}
I'd like to create an object used to store data, restricting read/write access.
For example :
OBJ obj1;
OBJ obj2;
// DataOBJ has 2 methods : read() and write()
DataOBJ dataOBJ1 (obj1);
With the code above, I want obj1 to access write() method, while other OBJ objects (obj2 in this case) should only access the read() method.
Is it possible to create a DataOBJ class restricting rights like that ?
The classical "getter setter" does not suit my needs.
Thanks.
You can control access to write/read by template global reference obj1/obj2 like in this example:
class OBJ {
};
OBJ obj1;
OBJ obj2;
// RESTRICTED ACCESS
class DataOBJBase {
protected:
void write() {}
void read() {}
};
template <OBJ&>
class DataOBJ;
// ALLOW WRITE IF FOR obj1
template <>
class DataOBJ<obj1> : public DataOBJBase {
public:
using DataOBJBase::write;
};
// ALLOW READ IF FOR obj2
template <>
class DataOBJ<obj2> : public DataOBJBase {
public:
using DataOBJBase::read;
};
int main() {
DataOBJ<obj1> dobj1;
dobj1.write(); // cannot read
DataOBJ<obj2> dobj2;
dobj2.read(); // cannot write
}
I think your best bet is defining an interface for the read and write methods, and pass a read-only wrapper object (which implements write by throwing an exception) rather than the real object to anyone who should not get write permission.
Mind you, this does not stop malicious code from dissecting your wrapper object -- if you want to do that, the DataOBJ should live in a different process than the read-only clients, and the RPC mechanism at the process boundary needs to enforce the access permission.
You could do it with a set of different classes, with the "disabled" method throwing an exception.
Something like:
struct DataInterface
{
virtual void read(...) = 0;
virtual void write(...) = 0;
};
struct DataReadOnly : public DataInterface
{
void read(...) { ... }
void write(...) { throw write_not_allowed(); }
};
struct DataReadWrite : public DataInterface
{
void read(...) { ... }
void write(...) { ... }
};
A thought I have and is probably bad practice. Nevertheless, I'll answer the question as asked with something that came to mind:
Static variables.
class Foo
{
private:
int y;
public:
Foo();
~Foo();
void set(int);
int get(void);
};
Foo::Foo()
{
static int c = 0;
++c;
y = c;
}
Foo::~Foo()
{
--y;
}
int Foo::get(void )
{
if(y == 1)
return y;
else
//do return an error code or something
}
void Foo::set(int r)
{
if(y== 2)
y = r;
else
//Do nothing
}
int main()
{
Foo *x1 = new Foo(); //Gets assigned 1
Foo *x2 = new Foo(); //Gets assigned 2
return 0;
}
Edit: For clarification -- I left out the delete's, and what not as well as the logic for properly decrementing on the destruction as my answer is hashing an idea out there, versus coding for the OP.
I'm refactoring a large amount of code where I have to add an extra parameter to a number of functions, which will always have a value of a member of that object. Something like
class MyClass
{
public:
CMyObject A,B;
void MyFunc(CMyObject &Object);
// used to be void MyFunc();
};
Now, I'd actually like it to read
class MyClass
{
public:
CMyObject A,B;
void MyFunc(CMyObject &Object = A);
};
But I'm not allowed to have a default parameter that is a non-static member. I've read this similar question which suggest this isn't possible, but I'm wondering if there is any reasonable workaround. Reason being that 95% of the time the default parameter will be used, and thus using a default parameter would hugely reduce the amount of code I have to change. My best solution so far is something like this;
class MyClass
{
public:
CMyObject A,B;
void MyFunc(BOOL IsA = TRUE);
};
void MyClass::MyFunc(BOOL IsA)
{
CMyObject &Object = A;
if (!IsA)
Object = &B;
}
This is less than elgant, but is there a better way of doing this that I'm missing?
Edit: FWIW, the reason for the extra parameter is to externalize some state related members from the object in question to aid multi-threading.
How about :
class MyClass
{
public:
CMyObject A,B;
void MyFunc()
{
MyFunc(A);
}
void MyFunc(CMyObject &Object);
};
?
Another way:
class MyClass
{
public:
MyObject A,B;
void MyFunc(MyObject MyClass::*myObject = &MyClass::A) {
MyObject& obj = *(this->*myObject);
}
};
This makes it even impossible to pass in an MyObject member from another MyClass instance. Your three valid options to call MyFunc are .MyFunc(), .MyFunc(&MyClass::A) and .MyFunc(&MyClass::B)
i am trying to compile this very simple piece of code
class myList
{
public:
std::vector<std::string> vec;
class Items
{
public:
void Add(std::string str)
{
myList::vec.push_back(str);
};
}items;
};
int main()
{
myList newList;
newList.items.Add("A");
}
what can i do to make this work without creating more objects that needed or overcomplicating stuff...
Add a couple of constructors and a pointer to the parent class.
#include <string>
#include <vector>
class myList
{
public:
std::vector<std::string> vec;
myList(): items(this) {} // Added
class Items
{
public:
Items(myList *ml): self(ml) {} // Added
void Add(std::string str)
{
self->vec.push_back(str); // Changed
};
myList *self; //Added
}items;
};
int main()
{
myList newList;
newList.items.Add("A");
}
You need the myList() constructor, so it registers instances of itself with the instance of the inner class member variable. Then you need the Items constructor to store the pointer to the outer myList class instance. Finally in the Add method, you need to reference vec in the stored myList instance.
As Catskul points out, the Item constructor mustn't actually do anything with the myList pointer it receives. I'd also like to say that though this answer is closer to the original intent, steveth45's answer is closer to what you would want to do in a real program.
This way you aren't exposing your class members directly. Your example seems over-architected a bit. Why put a std::vector into a class and then expose it as public?
class myList
{
private:
std::vector<std::string> vec;
public:
void Add(std::string str)
{
vec.push_back(str);
};
};
int main()
{
myList newList;
newList.Add("A");
}
Unlike Java, inner objects in C++ don't have access to an outer 'this' pointer ... if you think about it there may be cases where there isn't one to reference.
Richard Quirk's solution is the nearest you can get in C++
Inner classes are only related by name. You can't refer to the vector in the base class like that.
You either need to move the vector in to the inner class or store a reference to it.
While this post is a few years old I might be able to add something useful to it. While I will say that the design of the class in the original post doesn't look that great, there are times where it's useful to have an embedded class be able to access the containing class. This can easily be done without storing extra pointers. Below is an example. It should work as I took it from some existing code and changed some names around. The key is the EmbeddorOf macro. Works like a charm.
//////////////////// .h file /////////////////////////
struct IReferenceCounted
{
virtual unsigned long AddRef() = 0;
virtual unsigned long Release() = 0;
};
struct IFoo : public IReferenceCounted
{
};
class Foo : public IFoo
{
public:
static IFoo* Create();
static IFoo* Create(IReferenceCounted* outer, IReferenceCounted** inner);
private:
Foo();
Foo(IReferenceCounted* outer);
~Foo();
// IReferenceCounted
unsigned long AddRef();
unsigned long Release();
private:
struct EIReferenceCounted : IReferenceCounted
{
// IReferenceCounted
unsigned long AddRef();
unsigned long Release();
} _inner;
unsigned long _refs;
IReferenceCounted* _outer;
};
//////////////// .cpp file /////////////////
#include <stdio.h>
#include <stddef.h>
#include "Foo.h"
#define EmbeddorOf(class, member, this) \
(class *) ((char *) this - offsetof(class, member))
// Foo
Foo::Foo() : _refs(1), _outer(&this->_inner)
{
}
Foo::Foo(IReferenceCounted* outer) : _refs(1), _outer(outer)
{
}
Foo::~Foo()
{
printf("Foo::~Foo()\n");
}
IFoo* Foo::Create()
{
return new Foo();
}
IFoo* Foo::Create(IReferenceCounted* outer, IReferenceCounted** inner)
{
Foo* foo = new Foo(outer);
*inner = &foo->_inner;
return (IFoo*) foo;
}
// IReferenceCounted
unsigned long Foo::AddRef()
{
printf("Foo::AddRef()\n");
return this->_outer->AddRef();
}
unsigned long Foo::Release()
{
printf("Foo::Release()\n");
return this->_outer->Release();
}
// Inner IReferenceCounted
unsigned long Foo::EIReferenceCounted::AddRef()
{
Foo* pThis = EmbeddorOf(Foo, _inner, this);
return ++pThis->_refs;
}
unsigned long Foo::EIReferenceCounted::Release()
{
Foo* pThis = EmbeddorOf(Foo, _inner, this);
unsigned long refs = --pThis->_refs;
if (refs == 0)
{
// Artifically increment so that we won't try to destroy multiple
// times in the event that our destructor causes AddRef()'s or
// Releases().
pThis->_refs = 1;
delete pThis;
}
return refs;
}
Nick
You can simplify this by the following construct:
typedef std::vector<std::string> myList;
Really why don't you use the STL vector directly?
This way you get all the standard algorithms work with the
data.