We have the following class structure in our code
Class A: public CDialog, public Base1, public Base2
{
};
In implementation of Class A we have the following:
BEGIN_MESSAGE_MAP( A, CDialog )
ON_WM_SIZE()
END_MESSAGE_MAP()
Please note Base1 and Base2 doesn't inherit from CDialog or any other MFC classes.
On VC6 the compilation is successful. But on VC9 we get the following error code:
error C4407: cast between different pointer to member representations, compiler may generate incorrect code.
This error code is pointing to the location of ON_WM_SIZE.
Could anyone possibly tell me a solution. Thanks in advance.
Gamer
I just solved an instance of this problem; found this question with a web search.
In my case I also had a dialog class inheriting from more than one class: CDialog and ConfigurationTab, which is an internal interface.
The compiler warning was silenced by changing:
class Foo : public ConfigurationTab, public CDialog
with:
class Foo : public CDialog, public ConfigurationTab
We discovered this situation when the offending dialog crashed inside a ON_BN_CLICKED method at an assignment to a DDX variable. The DDX variable was mysteriously uninitialized at that line, when we were sure it was initialized.
I don't have an installed V9 handy, but i can see that between VS6 and VC8 the ON_WM_SIZE define has changed to be semantically the same but far more stringent in what it accepts. VC6 used C casts, where VC8 is using C++ casts which catch more problems.
We would need to see the actual declaration from your class of the OnSize method i think to be able to determine what is going wrong here.
Just guessing, been a while since I did MFC but it looks like it gets confused of your multiple inheritance
BEGIN_MESSAGE_MAP( class, baseclass )
expands to calling a method in 'class' so since A is multiple inherited its uncertain which of them to use, maybe you have the same method in several of the base classes?
in my case, the class Base2 has virtual method. eg.
class Base2
{
virtual void method(){};
}
and the warning occurs when I use
Class A: public CDialog, public Base1, public virtual Base2
{
};
to define the class A.
If I remove the virtual keyword here.
Class A: public CDialog, public Base1, public Base2
{
};
then the warning disappeared. Please note I didn't remove virtual in the body of Base2. Just in class A definition.
Hope it can help you.
Related
What am I doing wrong here? I cannot believe the below doesn't compile. Do you need to use a shared pointer cast or something?
struct Base
{
};
class Child : Base
{
};
int main()
{
std::shared_ptr<Base> p = std::make_shared<Child>();
}
The error I get with Microsoft compiler is
error C2440: 'initializing': cannot convert from 'std::shared_ptr<Child>' to 'std::shared_ptr<Base>'
It does work. It's just that Base has private inheritance.
struct Child : Base{};
or
class Child : public Base{};
are fixes. Interestingly std::static_pointer_cast and company do exist; but you don't need them here. See https://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast
Although #Bathsheba's and #divinas's answers solved this issue, none of them explained why is this the solution, and I think it's important for future viewers to know why is it the problem in this case.
When you are trying to create a pointer to the base class Base you are trying to get an access to all of the public members of the base that belong to the derived class (in this case Child). If the derived class privately inherit the base class (or protected inherit it), all of the members that labeled as public in the base class, inside the derived class now labeled as private (or protected). Which means that the attempt to access them as public members will raise an access privileges violation issue. Because the access privileges is known at the compile time, this is a compilation error.
The solve, as mentioned in previous responses, is to inherit the base class using public inheritance. Which is the default inheritance in structs and non-default inheritance in classes.
You should use public inheritance instead:
class Child : public Base
{
};
My company uses Parasoft to validate the correctness of our c/c++ program.
In the source code, many classes are not used as base class and they don't have virtual member functions. But they inherit from other class. Here is the sample code:
class class_a : public base{
protected:
int* pa;
public:
class_a();
~class_a(){free(pa);};
int* get_a(){return pa};
...
}
However, parosoft says:
Destructor ~class_a should be virtual
If I change the destructor to be virtual, the violation disappears.But I don't think this is the correct way to fix it.
So, Is this just false violation message or are there actually some flaws in our code?
What may cause this kind of parasoft error?
Under what conditions will parasoft show the same error message?
Follow up:
Many of these classes define functions that are totally the same with their base class.These functions are non-virtual.
Just let the tool know the class isn't intended as a base class :
class class_a final {
The tool should know out that it's pointless to have a virtual destructor in a final class.
The reason is rather simple. Because the base class has a virtual member function but its destructor is non-virtual.
Goal:
Sharing a base class with the same functionality except only a few descendants which merely hides methods (getters and setters) as they instantiate and free a protected or private pointer.
Problem:
When re-declaring the setter only I get this error when invoking the getter.
1>c:\projectengine\problem\main.cpp(8): error C2660: 'cDerived::SomeClass'
: function does not take 0 arguments
The getter isn't really needed but why disclose functionality if it's there already.
Conclusion:
cBase::SomeClass() is untouched by cDerived.
When commenting out the next line, no compile error (of course):
virtual void SomeClass( cSomeClass* value ) override {}; // setter, C2660
However that would work, and thus not changing anything, there rises a risk for a memory leak. On the other hand, this accidental derivative should inherited the rest of the functionality of cBase which is a descendant by itself.
Should I rewrite cBase or is it possible to hide only the setter in cDerived?
The code with the error:
main.cpp
class cSomeClass
{
};
class cBase : public cAbsoluteBase
{
public:
cBase() : m_pSomeClass( 0 ){}
virtual cSomeClass* SomeClass(){ return m_pSomeClass; }
virtual void SomeClass( cSomeClass* value ){ m_pSomeClass = value; };
protected:
cSomeClass* m_pSomeClass;
};
class cDerived : public cBase
{
private:
// hide these
//virtual cSomeClass* SomeClass() override { return m_pSomeClass; };
virtual void SomeClass( cSomeClass* value ) override {};
};
cDerived derived;
int main()
{
cSomeClass* someClass = derived.SomeClass(); // C2660
return 0;
}
You need a using declaration. Otherwise, overloads in the derived class hide the functions in the base class. (Because usually this is an error. If you had to specialize one overload, usually you have to specialize all of them.)
I'm not sure I could follow your description accurately, but from the code snippets, it looks like you want to publicly inherit from a class, but remove one of the methods of the base classes interface.
That is possible, it is even possible to do accidentally, but it is a very bad idea™. Public inheritance is an “is-a” relationship. If you have a class B publicly inheriting from class A, then what declaring that relationship means is “objects of type B may be larger than those of type A, but apart from that, you can use a B wherever an A is expected.” Obviously Bs may have additional behavior, but public inheritance promises that they work as fully functional As. (This is known as the “Liskov Substitution Principle,” by the way.)
Note that this is also why one of the early textbook examples for inheritance was utterly broken: Having Square inherit from Rectangle. Yes, a square is a rectangle, but that doesn't mean it is sound OO design to have Square publicly inherit from Rectangle. Because sub-classes having additional restrictions over their parent classes breaks a lot of otherwise perfectly valid and useful code, by not adhering to the established interface contract. (In the case of squares, they break the contract clause that you should be able to change the sides of a rectangle independently from one another. In your case, you seem to be removing parts of the interface altogether.)
Sorry for long winded title, this makes a lot more sense with an example.
Suppose we have a class A:
class A {
public:
void someFunction();
void someOtherFunction();
};
And another class that privately inherits from A. However, we re-declare one of the inherited functions as public:
class B : private A {
public:
A::someFunction;
}
When this code is processed by Doxygen, it does not recognise the public declaration of someFunction in class B. Instead, it shows someFunction as a privately inherited function. This is incorrect.
Is anybody aware of how to fix this?
Cheers
I can't comment so I'll post this as an answer.
When you do private inheritance in C++, it's a variant of composition or agregation. It's like a "Car - has an - Engine" relationship, so maybe Doxygen has a problem with this syntactic way of doing things. You could probably turn this around a bit to get a good public inheritance or a real composition.
If you want to know more about private and protected inheritance : http://www.parashift.com/c++-faq-lite/private-inheritance.html
Hope it helps !
I was asked in an interview that what is the usage of virtual keyword with a class declaration in C++ and I answered that virtual keyword cannot be used with a class declaration in C++. The interviewer said that it is possible and asked me to test it later.
Now that I have checked it myself I have come to know that this is possible and this is not a compiler error. In fact, when I do something like this with a Visual C++ compiler:
virtual class Test
{
int i;
};
I get a compiler warning "warning C4091: 'virtual ' : ignored on left of 'Test' when no variable is declared". I haven't been able to find out yet that what this warning means and further what is the usage of virtual keyword. If there is no helpful usage, then why is this allowed in the first place and why is this not a compiler error.
That's a bug in VC++. Comeau and gcc both reject the code.
virtual can be used when deriving from another class:
class Foo : public virtual Bar
{
}
This is used to avoid having multiple versions of the same base class when using multiple inheritance. Wikipedia has a good article on the subject.
You simply can't use virtual for a class. It only works for member functions
You're looking at the wrong sort of usage - I'm pretty sure that the interviewer was referring to virtual base class declarations, like so:
class A : virtual public B, public C {
...
};
This is a common idiom and used to get around the "multiple base class" scenario in diamond-shaped inheritance trees. The typical problem with them is that you inherit from both class B and class C and they share the common ancestor A. If you go 'up' the inheritance tree you'll hit the ambiguity as to which instance of 'A' you're supposed to use. If B & C have A as a virtual base class instead, they will refer to the same instance of A, which solves this problem.
You can find a more exhaustive description with class diagrams here.
Maybe he was referring to virtual inheritance / virtual base classes? E.g.
class A : virtual public B
{ ... }
That would technically be part of the class definition.
Could he have been talking about using a virtual base class in the class declaration?
Like this:
class CashierQueue : virtual public Queue {};
This is used in multiple inheritance when you want to avoid a derived class having multiple copies of the member data when it inherits from two or more classes that share the same base class.
class Queue {};
class CashierQueue : virtual public Queue {};
class LunchQueue : virtual public Queue {};
class LunchCashierQueue : public LunchQueue, public CashierQueue {};
See http://msdn.microsoft.com/en-us/library/wcz57btd(VS.80).aspx