I am trying to inherit CObject but am failing to do so.
My class looks like this:
class CCanMessage : public CObject
{
public:
CCanMessage(void);
~CCanMessage(void);
unsigned int m_id; //can-id
CANMessageTypes m_msgType; //this is an enum
unsigned char m_len;
char *m_pCmdStr;
};
The constructor and destructor are empty.
When I compile I get error C2248: 'CObject::CObject' : cannot access private member declared in class 'CObject'. I have been looking for an explanation for some time now without finding one. I assume the error is embarrassingly simple, but I just can't seem to find it.
Worth noting is that if I don't use the CCanMessage class anywhere the compilation error disappears. The error points to the declaration of the class and not to any place I use the class.
I presume your issue is with this part from CObject (afx.h):
private:
CObject(const CObject& objectSrc); // no implementation
void operator=(const CObject& objectSrc); // no implementation
Try to provide implementations for the copy constructor and assignment operator for your CCanMessage.
Related
I want to write an abstract class so whoever inherits it, he will be forced to implement a specific function inside it.
For example I wrote:
class Car {
virtual double getFuelConsumption(int speed) = 0;
};
But If I write the following it compiles with no compilation error (even though it didn't implement getFuelConsumption())
class meme : public Car {};
Update:
Why I'm getting error:
(I know that if it's exactly a car then it doesn't have getFuelConsumption implemented what what if it's a class that inherits class Car, I want this to work)
double getPetrol(std::vector<Road> roads, const Car &car) {
car.getFuelConsumption(1);
}
> 'this' argument to member function 'getFuelConsumption' has type
> 'const Car', but function is not marked const
The code you wrote is OK, as long as nobody instanciates a meme. This is by design.
As far as the compiler is concerned, your plan might very well be:
class meme : public Car
{
};
class ConcreteMeme : public meme
{
virtual double getFuelConsumption(int speed) {return 2.0;}
};
Since you may want intermediate interfaces, there's no issue. The problem shows only when you try to instanciate a class that has a pure virtual method. If the compiler were to prevent you from having meme, you'd end up in a situation where you can't have ConcreteMeme.
The code you have is fine, meme will not be usable at all without the pure virtual method(s) being implemented. The only reason it compiles now is that you haven't actually tried to use it.
Sometimes, we need to provide a specific constructor solely for test usage. How can we force such constructor is solely used in test code, nowhere else.
I just wonder if this is achievable in c++11/14. e.g.,
class A {
public:
A() = default; // used only in test code
}
class A_Test : public ::testing::Test {
private:
A a; // it is ok.
};
class A_Production {
private:
A a; // compiler error
}
I could imagine to use friend decorator and put the specific constructor in protected to limit the access. but there are other existing friends in legacy code too. Is it possible to make a custom specifier like protected in c++1x?
any ideas?
You could use the Passkey Idiom:
Instead of a direct friendship, you limit the access to A from A_Test through the indirection provided by ConstructorKey, which A uses in its interface where it wants the friends of ConstructorKey to access.
class A {
class ConstructorKey {
friend class A_Test;
private:
ConstructorKey() {};
ConstructorKey(ConstructorKey const&) = default;
};
public:
// Whoever can provide a key has access:
explicit A(ConstructorKey); // Used only in test code
};
class A_Test : public ::testing::Test {
private:
A a {ConstructorKey{}}; // OK
};
class A_Production {
private:
A a {ConstructorKey{}}; // Compiler error
};
I can think of several ways to do that.
Make the constructor protected, with only the test subclass using it.
Add a forward declaration to some dummy class, class TestClassThatShouldNotBeUsedInProductionCode;, then declare a constructor that takes a reference to this class as a parameter:
A::A( /* other constructor arguments */,
const TestClassThatShouldNotBeUsedInProductionCode &)
This constructor can simply ignore this parameter altogether. Your test module can define this dummy, empty class: class TestClassThatShouldNotBeUsedInProductionCode {};, and be able to construct your A class using it. Only your test module would be able to use this constructor, then, and its name makes it pretty clear what the purpose of this is. There isn't really any way to define certain translation units as "real" code versus "test" code, in C++, you just want to implement a clear policy that would be hard to violate accidentally.
Some variations are possible, such as using an inner class instead of forward-declaring a standalone class. The inner class could only be instantiated only by the test code.
As an alternative, in the cpp file that does the testing of A:
#define private public
#include "ClassA.h"
// ready for testing :)
I'm somewhat new to C++ and am trying to understand the syntax and its behaviour. In particular, after quite a bit of googling and research, I was unable to find out why the following code won't compile:
class base {
public:
base (const int);
};
class child: base {
public:
child (const int);
};
child::child(const int num) : base(num) {}
but this will:
class base {
public:
base (const int);
};
class child : base {
public:
child (const int num) : base(num) {};
};
In the above case the linker fails with:
Undefined symbol base::base(int)
I feel like I'm making a very stupid mistake but the compiler's errors are completely unhelpful.
The compiler is telling you exactly what the problem is. You must define a constuctor for base if you invoke it, and you are invoking it from the derived class child.
Try adding this to your code:
base::base(const int num) {}
This ignores the given argument, but at least your code will compile.
I would probably remove the declaration for the base constructor and not pass any value to it from the child class unless it was actually used.
In the second case, the constructor is inline and never invoked so the compiler does not need to generate code for it, but if you try to actually construct a child object, you will get the same linker error.
The reason inline code is not generated is because you have no invoking call site. The whole purpose behind declaring code inline is so that it is inlined at the call site. Thus the compiler defers code generation for all inline code until it is actually called.
When you define the constructor within the class, the compiler doesn't actually look for the base class constructor until you try to actually instantiate a member of the class. Once you do that (via e.g. child a(5);), you will get the same error as above, see here. When you defined the constructor outside the class, though, it was attempting to link it even without the instantiation, resulting in the error even without child a(5);.
Let's suppose that I have the following classes declared in my MFC project:
class CProfession : public CObject
{
public:
CProfession();
virtual ~CProfession();
int ID;
CString name;
};
class CPerson : public CObject
{
public:
CPerson();
virtual ~CPerson();
int ID;
CString name;
int age;
CString email;
CList<CProfession, CProfession&> profession;
};
Due to the CList declaration (as it was shown right above), I get the following error:
error C2248: 'CObject::operator =' : cannot access private member declared in class 'CObject'.
I've already tried to implement many kinds of overloadings and copy constructors, but I didn't had any success. I realize that there are other possibilities for solving this error, such as using pointers, but I really looking for a solution that fits exactly in the code that I provided. Does anyone knows how to solve this?
Since operator=(const CObject&) is declared private in the base class you have to provide a public assignment operator in your derived class:
CProfession& operator=( const CProfession& other ) {
this->ID = other.ID;
this->name = other.name;
return *this;
}
Depending on the semantics you want to implement you may have to adjust the implementation to your requirements.
Also keep in mind the Rule of three, a rule of thumb claiming that if a class defines one of the following it should probably define all three:
destructor
copy constructor
copy assignment oprator
All of the above are implicitly implemented by the compiler unless they are declared by the programmer. The rationale of the Rule of three is that if one of the compiler-generated member functions does not fit the needs of a class and has to be defined by the programmer, then the others will probably not fit either.
I created my class CData and derived it from CObject, because I need to serialize it.
class CData : public CObject
{
DECLARE_SERIAL(CData);
public:
CData();
virtual ~CData();
virtual void Serialize(CArchive& ar);
//Data
CString m_strName;
ULONG m_ulID;
CString m_strCorps;
CPoint m_Coordinate;
short m_sStatus;
};
And I use a vector of type vector<CData> in my document class. I add new CData-objects to the vector during the runtime of the program using vecData.push_back(Data) (where Data is of type CData).
But when I try to compile this i get the following error:
error C2248: 'CObject::CObject' : cannot access private member
declared in class 'CObject'
I searched a bit and found out, that it has to do with the CObject-class to be non-copyable or something like this!?!?...
Does anyone know how to solve this problem?
CObject declares the copy constructor as private, so you need to implement the copy constructor (and assignment operator overload) for your class yourself. The CObject constructor documentation says:
The standard C++ default class copy constructor does a member-by-member copy. The presence of the private CObject copy constructor guarantees a compiler error message if the copy constructor of your class is needed but not available. You must therefore provide a copy constructor if your class requires this capability.
I hope this helps!
Did you happen to forget IMPLEMENT_SERIAL in the .cpp-file?