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.
Related
My actual code (class name changed, some cut, as it is company confidential, but there is only one compiler error, so what I cut should not be affecting things)
class Xyz
{
public:
virtual void vPrintStatus() const;
};
and its mock
class MockXyz : public Xyz
{
public:
MOCK_CONST_METHOD0(vPrintStatus,
void());
};
Which gives me a compiler error : error: ‘vPrintStatus’ is not a type
#includes, etc are OK. The compiler is obviously finding vPrintStatus, as, if I change it to something undefined:
MOCK_CONST_METHOD0(independence,
void());
I get error: ‘independence’ has not been declared.
So, the compiler finds vPrintStatus and appears to know its type (or, at least, what type it is not).
I am sure that I am following the syntax for MOCK_CONST_METHOD0 - the mock macro shoudl be expecting a function name, not a type, as its first parameter.
What am I doing wrong?
The below error message:
error: ‘vPrintStatus’ is not a type
indicates that MOCK_CONST_METHOD0(vPrintStatus, void()); was parsed by a compiler as a declaration of a member function, named MOCK_CONST_METHOD0, taking two parameters, one of type vPrintStatus (hence the error), and another being a function pointer type (void(*)() after adjustment). Clearly, this means that the definition of macro MOCK_CONST_METHOD0 is not visible to the translation unit the mock declaration is part of. Make sure you have included <gmock/gmock.h> to that file.
I had a similar issues and it turns out I was trying to use:
MOCK_CONST_METHODO instead of
MOCK_CONST_METHOD0 (zero works much better the O)
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.
I am reusing a class from an old project and it has the following:
Header File
// forward class declarations
class TimeZoneInfo;
class DateTime
{
public:
// constructors
DateTime();
static TimeZoneInfo m_Info;
};
Body File
TimeZoneInfo DateTime::m_Info; <-- Error Here
DateTime::DateTime()
{}
//blah blah
When I go to build this I get the error :
Error: Incomplete type is not allowed:
Why was this working before? (I am now using Visual Studio 2013)
And how can I solve this? Thanks
Why was this working before?
Impossible to say.
And how can I solve this?
Include the header that defines TimeZoneInfo from the source file, before the variable definition.
"Incomplete" means that the type has been declared, but not defined, so can only be used in limited ways. Specifically, you can declare a variable of an incomplete type, but can't define it.
It is ok to have a static incomplete type member. However, its type should be defined before the definition of the static member, i.e.
TimeZoneInfo DateTime::m_Info; // class TimeZoneInfo must be fully defined before this line
Related: Static field of an incomplete type - is it legal?
I have two classes. In the main class I have a process that is step by step and can be stepped though, I have implemented this as a state machine. To help keep the machine easy/friendly I created another class that holds information about the current state of the machine. In the main class I then added a reference to it as such
CAnimateMachine *m_AniMach;
After some actions happen I call a function in the main class to instantiate variables within my state machine object. Each call to this function AniInit() should basically "reset" the state machine by instantiating the variables to the "initial state".
My issue is I am not sure how to instantiate my m_AniMach properly. I am used to C# where I can just do
m_AniMach = new CAnimateMachine();
to "erase" the old object and instantiate a new one. Though, from what I have read, I can not be so cavalier in C++. What is the proper way to "re-instantiate" this variable in my init method?
Could I use the new operator m_AniMach = new CAnimateMachine() and then in the main class' deconstrutor do delete &m_AniMach?
EDIT: juanchopanza's answer makes sense to me. Though I keep getting an error when trying to compile. I am not exactly sure what the error is trying to tell me, I think it is telling me that my class isn't public when it is? I reviewed the C2248 MSDN article but I do not see how it relates to my situation.
error C2248: 'CObject::operator =' : cannot access private member declared in class 'CObject'
include\afx.h(562) : see declaration of 'CObject::operator ='
include\afx.h(532) : see declaration of 'CObject'
occurred in the compiler generated function 'CAnimateMachine &CAnimateMachine::operator =(const CAnimateMachine &)'
Here is my CAnimateMachine class
class CAnimateMachine
{
public:
CAnimateMachine();
int startX,startY;
};
And this is how I instantiate it
m_AniMach = CAnimateMachine();
And how it is defined
CAnimateMachine m_AniMach;
There seems to be no reason to use a pointer. You can use an object instead:
CAnimateMachine m_AniMach;
in which case it will get default initialized when an object of the type that holds it gets instantiated. To "re-initialize" it, you can say
m_AniMach = CAnimateMachine();
If you do this, you will not have to worry about things like following the rule of three or other dynamic allocation pitfalls.
I am writing a class called BleakField, and it uses an enumeration called DrawStyle.
DrawStyle is forward declared in the area marked protected (it needs public access but the class has protected members of type DrawStyle) as such:
class BleakField {
protected:
enum DrawStyle;
DrawStyle type;
It is fully defined right after public:
public:
enum DrawStyle : bool {DRAW_SOLID = true, DRAW_TRANSPARENT = false};
Inside the constructor for the class, I set "type" to DRAW_SOLID.
BleakField::BleakField() {
type = DRAW_SOLID;
These are the only areas that deal with this type in the class so far (and the rest of the class is properly defined I just didn't include it because it isn't necessary but I obviously closed the brackets and everything), and I am getting
IntelliSense error: a value of type "BleakField::DrawStyle" cannot
be assigned to an entity of type "BleakField::DrawStyle"
I am highly confused as to why I cannot assign values of a type to entities of the same type. I figured it could just be a glitch and I tried deleting and retyping it, but it is still doing this. Does anyone know why this is happening and how I can avoid it?
EDIT: It gives me a warning about the change from protected to public, indicating that the protected status gets overwritten by the public one. Also I have done this exact thing before and not gotten that error, which I find odd. And I can definitely forward declare enums, but even moving sections around so that I don't need to didn't solve it. Apparently I can compile the program with half the code unfinished and it worked, but the error is still there. So I guess the compiler thinks it is fine, just not Visual Studio.