My aim was to implement a class that can be accessible from anywhere, providing key value pairs;
class SharedResources
{
public:
static QMap <QString,QVariant> *preferences;
};
//initialization
SharedResources.preferences = new QMap<QString,QVariant>();
//store data
SharedResources.preferences->insert("some_data",some_data);
//access data
some_data = SharedResources.preferences->value("some_data");
but this code does not compile.
First error (got a similar at every usage):
/file:line: error: expected unqualified-id before '.' token
SharedResources.preferences = new QMap<QString,QVariant>();
^
I definitely broke some c++ rules, but what those are?
Update: Using :: the error is:
/file:line: error: undefined reference to `SharedResources::preferences'
It's better in such a case to use statically rather than dynamically allocated memory (i.e. without new).
Your problem is that you have to declare and define your static field as well. In the header file you only declare it, it should be defined somewhere in the cpp file like:
// this defines the variable, with default ctor (w/out parameters)
QMap<QString,QVariant> SharedResources::preferences;
Of course you have to link the appropriate object file to your other modules (apart from using header file with the declaration).
As I already pointed out in the comment, static members are accessed via :: and not via .
I guess the reason is that . is an operator that needs an object, while static members are accessed without an object.
Related
I have a class which includes among its members an object of another class.
The header file looks like this:
class LinxArduinoEthernetListener : public LinxListener
{
EthernetServer ArduinoTcpServer(uint16_t);
Where EthernetServer is itself a class (defined in the Arduino EthernetServer.h library).
Because I do not know the port at compile time, but the server object should be a member of the listener class, I allow the server object to be initialized in the class constructor, and then attempt to reassign that object later, using the following code (in the corresponding .cpp file):
ArduinoTcpServer = EthernetServer(port);
Where "port" is a uint16_t. As far as I know, this is the correct way to reassign to an object variable a newly constructed instance.
And yet, the compiler gives me the following error:
LinxArduinoEthernetListener.cpp:122: error: invalid use of member
function (did you forget the '()' ?)
ArduinoTcpServer = EthernetServer((uint16_t)port);
I think this may be related to the error I get for the immediately subsequent function call:
LinxArduinoEthernetListener.cpp:123: error:
'((LinxArduinoEthernetListener*)this)->LinxArduinoEthernetListener::ArduinoTcpServer'
does not have class type
ArduinoTcpServer.begin();
But I would say it clearly does have a class type, namely the EthernetServer class, as specified in the header file.
What am I doing wrong here?
EthernetServer ArduinoTcpServer(uint16_t); declares a member function named ArduinoTcpServer. To declare a member variable, omit the parameter type and parentheses. Also add a constructor to initialize the member variable, e.g. :
class LinxArduinoEthernetListener : public LinxListener
{
public:
EthernetServer ArduinoTcpServer;
LinxArduinoEthernetListener(uint16_t port)
: ArduinoTcpServer(port)
{
}
};
So, the issue was the declaration of the server object.
Initially, I had it declared as follows:
EthernetServer ArduinoTcpServer(22);
But I would get an error about "expected identifier before numeric constant" referring to the 22. So I googled it, and found someone suggesting that (in some context I don't remember) specifying only the type was sufficient to call the constructor matching that prototype. Doing so allowed the compiler to continue, so I assumed that was valid. However, it seems not.
The real issue is that the compiler Arduino IDE uses requires braces initialization, e.g.
EthernetServer ArduinoTcpServer{22};
That seems to work.
I am working on an assignment, and while I don't have any issues with the actual assignment, I want to make my code "proper." I am trying to define a static variable in my header file. I want it to be static so that all instances of this class can access the same variable. I don't want to extern it either, I want just this class to have access to it.Then I am trying to define it in the actual file (not header) but I keep getting an error about not being able to cast. I just want to learn how to properly do this to have cleaner code.
The definition of your field stays inside the class:
class AddrSpace
{
List *availSpots;
};
The full name of this variable will be AddrSpace::availSpots. C++ requires to define static variables (including the static fields of the classes) explicitly. I would not say this is fully logical because compiler already has everything to generate all necessary stuffs. Nevertheless this is so. The definition in your C++ file should look like:
List *AddrSpace::availSpots = new List();
Next time please add the source directly into the question.
class ClassObject {
public:
ClassObject();
virtual ~ClassObject();
private:
int x;
};
int ClassObject::x=10;
Why does it fail to compile?
I think that if static members can be initialized this way, then it should also be possible for non-static ones.
Static members are special. They have a memory allocated to them as soon as the class is defined. And no matter how many objects of that class we create all those objects refer to the same piece of memory.
This is not the case with non static members. Unless you create an object of that particular class, the non static members are not allocated any memory and hence trying to instantiate them in the above way leads to compiler error.
I'm guessing you mean declaring the value used to initialise x for any new ClassObject, i.e. you mean that as equivalent to
ClassObject() : x(10) { }
The problem with your syntax is that the compiler needs to generate code to do that initialisation in every ClassObject constructor; i.e. it can only work if the int ClassObject::x = 10; initialisation is available in the compilation unit that defines all constructors, and any compilation units that generate one implicitly. And the only way to guarantee that is if the value is set inside the class definition, not outside it as you have. (However this is now possible in C++11 - see the link in tacp's comment.)
If we did want to make your syntax work, then we'd need to store the declared value as a hidden static somewhere in a way that any constructors would pick it up and know to use it as the initial value for x. However this static may or may not exist, and the only point we can know that for a constructor in a different compilation unit is at link time. Hence we either generate extra, redundant code to initialise x from this hidden static if it exists (or redundant data) or we mandate link-time-code-generation to solve this, which puts a large burden on the compiler developer. It is possible, yes, but it's simpler all around if this isn't allowed.
I have a question regarding static variables, or some other way to do so.
I have a master class, PatternMatcher. I have several derived units from that, depending on what matcher is used. Now each subclass needs to store a vector of floats, but within each class it is constant. The data for that vector is read during initialization, and can be up to 1GB in size (smallest I have is 1MB, biggest is 1GB).
Currently when I have for example two instances of Matcher_A, it would allocate twice the memory. I do not know in advance which matchers are to be used (per run it will be three matchers, and you can use the same matcher several times). I would prefer to not check during run time whether the wanted matcher is already initialized somewhere, since this would require additional code for every change I do.
Currently I allocate the 3 matchers with
PatternMatcher* a = new PMMatcherA();
PatternMatcher* b = new PMMatcherB();
PatternMatcher* c = new PMMatcherC();
, but since they are user selected, it could happen that A and C are the same for example. When I run a check via typeid(a).name();, it would give me PatternMatcher as result, never matter what class I used to initiate with. PatternMatcher basically is purely a virtual class.
I always thought that static means that a variable is constant over different allocations, but when I define my vector as static, I would get a linker resolve error. In an earlier iteration, I had these vectors global, but would prefer them to be localized to their classes.
What are the keywords I need to use to have the vector from on initialization be available for the next initialization already? A simple check if the vector size is greater than 0 would already be enough, but every object uses its own vector.
static keyword is a way to go - that would store exactly one copy of a member for the whole class. What you were missing is an actual declaration of such static in a compilation module so that the linker can use it. For instance:
header file foo.h:
struct Foo {
static int s_int;
}
source file foo.cpp:
#include "foo.h"
int Foo::s_int; // optionally =0 for initialization
The second part is vital as this will allocate a memory space for the object to be used as a static member.
Keep in mind, though, that:
static members will all be initialized before the main(), which means your 1GB of data will be read regardless of whether anyone ever uses that particular class
You can work around the abovementioned issue, but then you will have to be checking if the data load and initialization has happened during run-time
There's another option for you, however. If you store your floats "as-is" (i.e. 32 bits per each, in binary format) you can just simply "map" the files into memory spaces and access them as if they were already loaded - the OS will take care of loading appropriate 4K pages into RAM when needed.
Read more about mmap at http://en.wikipedia.org/wiki/Mmap
Yes, static is what you need. You can use it like this:
class MyClass
{
private:
static std::vector< float > data_;
};
std::vector< float > MyClass::data_;
Please note that in the class itself you only declare static variables. But you also need to define them outside of the class exactly once. That's why we have the line std::vector< float > MyClass::data_;, if you omit that, you will have linker errors.
After this, every object of MyClass class will share the same data_ vector.
You can operate it either from any object of the class:
MyClass a;
a.data_.push_back(0);
or through the class name:
MyClass::data_.push_back(0);
when I define my vector as static, I would get a linker resolve
error.
This is because you declare the static variable (in your header file) but you never explicitly initialize it in one of your implementation file (.cpp).
For example:
//AClass.h
class AClass
{
private:
static std::vector<int> static_vector;
};
and in the .cpp implementation file:
std::vector<int> AClass::static_vector;
I want to access a private data member in a class. There is no member function in the class to access the private data member. It is private.
I want to take the class and some how crack it open. One method was to copy the declaration of the class, make the private member public and call the new class class something_else. Then I do a reinterpret cast and copy the original object. This works. But I want something more elegant ... or perhaps generic ... or just another way.
What options are there? Can I use void*? Can I memcpy the class into another empty class? What are ways to do this??
%
I am assuming that
You've already been through "breaking encapsulation is bad" stage,
Exhausted other possible solutions,
Can't change class' header.
There are a few ways to subvert access to a class's private members, as demonstrated in GotW #76.
Duplicate a class definition and add a friend declaration.
Use evil macros: #define private public before including class' header.
Write a class definition with identical binary layout and use reinterpret_cast to switch from original class to a fake one.
Specialize a template member function if there is one (the only portable solution).
With the idea you suggest in your question, you don't need to copy the original object. If you write your own "all public" variation of the real class declaration, then cast a pointer to that new type, you can directly access the object through it.
The reason why none of this is a good idea is simple. You must be manipulating objects of a class of which you don't control the source (otherwise you'd be able to modify the source to give you the access you need). But if you don't control the source, then what if the maintainers change the layout of their class? Your duplicated version will no longer match up, and there will be no way for the compiler to detect this mismatch. The result will probably be memory corruption at runtime.
Since it's incorrectly understood, I have to clarify. All the following solutions do not require you to recompile the object. To use a class in your code, if it's compiled into an object file, you should include header file with the declaration of that class.
#include <class.h>
ObjectFoo instance;
It is possible (but dangerous unless you're careful) to change the header (a) or copy the header to another place and include that header (b), without recompiling the class itself.
#include <class_fixed.h>
ObjectFoo instance;
Your code, where you included the new header will just think that within the object file (which you haven't recompiled!) he will find implementation of the class declared as in class_fixed.h. While there persists the class declared as in class.h. If you change offsets of members (add new members for example) in your new header, you're dead and the code will not work properly. But just changing the access works fine. Compiled code doesn't know about access, this matters only at the compilation strange.
This is not always harmful. In everyday life you encounter such a change when you install new version of a library into your system and do not recompile all programs that depend on it. But it should be handled with care
There are several solutions.
memcpy()Don't! Do not memcpy as object copying sometimes undergoes specific policy imposed by the class designer. For example, auto_ptrs can't be just memcopied: if you memcopy the auto_ptr and then destructor is ran for both, you'll attempt to free the same memory two times and the program will crash.
Change private: to public: in header or with macroIf your license permits it, you may solve your problem by editing the header file that comes with the implementation of the class. Whether the source code of the implementation (i.e. cpp-file of the class) is under your control doesn't matter: changing private to public for data members (in header) suffices and works just fine even if you're given a binary-only library that contains class definition. (For member functions changing access sometimes changes its internal name, but for MSVS and GCC it's ok.)
Adding a new getter functionWhile changing private to public is nearly always ok (unless you rely on specific compile-time checks that should break the compilation if class has certain member accessible), adding new getter function should be performed carefully. The getter function should be inline (and therefore defined in the header file of the class).
reinterpret_castThe cast works just fine if you're NOT casting a pointer to dynamic base class (dynamic means "with virtual functions or bases") whose actual instance at the moment of casting can be derived from the class at the particular piece of code.
protected:And just in case you forgot. C++ can declare members protected:, i.e. accessible only to the classes derived from the given. This may fulfill your needs.
You can, but you shouldn't. The objects are just memory. You can certainly cast the pointer into an equivalent class that has the same members but where everything is public. But why do you want to do this? Do you have somebody else's code that you need to work with? Get them to add proper accessor methods. Do you really need to treat them as public members? Change the class.
I'm not really sure what you are trying to do, but it's probably a mistake.
I agree with the "edit the source" comment, but I think you should add a method, not just comment out the 'private'.
You must have the declaration of the class, so you presumably have the header but possibly not the .cpp/whatever file. Add an inline member function to the class in a copy of the header, and include this header instead of the original. You should still be able to link to the object file for the inaccessible source code.
Of course this counts as an evil hack, bypassing the protections built into the language rather than working with them. That's why I suggest the minimally evil hack - don't make everything private, and if you can get away with a getter (but no setter) do that. Of course the real minimal evil is not to do it, if there's any way at all to avoid it.
Remember, if this is someone elses class you're working with, the next version might be implemented differently and might not have that member at all.
Thank you ... I did want to show the code for my original fix. The reason as someone aluded to is that I cannot change the original code ... so I have to do a jail break.
#include<iostream>
using namespace std;
// Class Objectfoo
// Pretend Objectfoo lives somewhere else ... I cannot open him up
class ObjectFoo
{
private:
int datax;
public:
ObjectFoo() { datax = 100; }
void get() { cout << datax << endl;}
};
// Class ObjectBar
class ObjectBar
{
public:
int datax;
};
ObjectFoo FOOEY;
ObjectBar* touch_foo(int x, ObjectFoo* foo , ObjectBar* bar)
{
bar = reinterpret_cast<ObjectBar*>(foo);
bar->datax = x;
return bar;
}
int main()
{
ObjectBar* bar;
cout << "Displaying private member in ObjectFoo i.e. ObjectFoo.datax" << endl;
FOOEY.get();
cout << "Changing private member " << endl;
bar = touch_foo(5, &FOOEY, bar);
cout << "bar->datax = " << bar->datax << endl;
cout << "Displaying private member in ObjectFoo i.e. ObjectFoo.datax" << endl;
FOOEY.get();
return 0;
}
This works ... but I think I want something more generic ... or more flexible.
%