I have a base class:
#define OUT
#define NO_VTABLE __declspec(novtable)
class NO_VTABLE Foo
{
public:
virtual bool TestSomething() const = 0;
virtual bool TestSomething(OUT unsigned int& extendedInfo) const {
UNUSED(extendedInfo);
return TestSomething();
}
};
And a derived class:
class NO_VTABLE Bar : public Foo
{
public:
virtual bool TestSomething() const {
// Do the test, return the result...
}
};
Under GCC, the program compiles cleanly with -Wall -Woverloaded-virtual. Under Visual Studio, I get a dirty compile. TestSomething from above is Available shown below.
1> ...\derived.h(78) : warning C4266: 'bool DeviceState::Available(unsigned int &) const' :
no override available for virtual member function from base 'DeviceState'; function is hidden
1> ...\base.h(794) : see declaration of 'DeviceState::Available'
1> ...\base.h(787) : see declaration of 'DeviceState'
Removing NO_VTABLE makes no difference. The warning persists.
All the TestSomething are public and virtual in both the base and derived classes, so its not clear to me what is hidden from the caller.
I'm working through testing under Visual Studio, and I've encountered it on both Visual Studio 2005, 2008 and 2010. I still have other VS's to test, but at this point, I know its not a one-off.
I prefer not to turn off the warning because the file base.h is large with lots of classes, and it might encounter other problems in the future.
What does Visual Studio claim is hidden from the caller? What is the source of the warning under Visual Studio, and how do I clear it?
If you look up error C4266 you'll find that it says A derived class did not override all overloads of a virtual function. So for this compiler you'll need to override all of the overloads for the unsigned int & variant to be visible.
I haven't looked up in the language spec to see if this is conforming or not.
Related
I've got quit a huge project to fix, there is a bug I can't resolve by myself:
class CEntity
{
public:
CStudioHdr * GetModelPtr();
public:
CStudioHdr * InternalGetModelPtr();
static CStudioHdr * (ThisClass::* GetModelPtr_Actual) ();
}
Here is the function to cast to:
class GenericClass {};
typedef void (GenericClass::*VoidFunc)();
inline void *GetCodeAddr(VoidFunc mfp)
{
return *(void **)&mfp;
}
The line, which doesn't let me to complie the project:
void *callback = (void *)GetCodeAddr(reinterpret_cast<VoidFunc>(&CEntity::InternalGetModelPtr));
I get this error:
error C2440: 'reinterpret_cast' : cannot convert from 'CStudioHdr *(__thiscall CEntity::* )(void)' to 'VoidFunc'
I gues it's something wrong with msvc compilers:
Visual Studio 2012 (v110)
Microsoft Visual C++ Compiler Nov 2012 CTP (v120_CTP_Nov2012)
The remarcable moment is that there is another class:
class CAnimating : public CEntity
{
And if I move this function into this class, there are no errors.
I'm not sure if it's the best way to get a void pointer, is it correct for linux as well?
In My class, I've a static Clist variable declared in the following way:
#include<stdio.h>
#include<conio.h>
#include <afxtempl.h>
void otherfunc(CList<int,int> a)
{
}
class A
{
public:
CList<int,int> myvariable;
void myfunc()
{
otherfunc(myvariable);
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
a.myfunc();
getch();
return 0;
}
otherfunc() is not part of my class.
Where am I going wrong?
I have just pasted the code snippet with the problem. I have initiated it and everything works file except for the line where im calling otherfunc(). Its has no dependence over static keyword. Even if i remove static, i get the same error.
Edited : Here is the error tht I get :
C:\program files (x86)\microsoft visual studio 9.0\vc\atlmfc\include\afxtempl.h(776) : error C2248: 'CObject::CObject' : cannot access private member declared in class 'CObject'
1> c:\program files (x86)\microsoft visual studio 9.0\vc\atlmfc\include\afx.h(561) : see declaration of 'CObject::CObject'
1> c:\program files (x86)\microsoft visual studio 9.0\vc\atlmfc\include\afx.h(532) : see declaration of 'CObject'
1> This diagnostic occurred in the compiler generated function 'CList<TYPE,ARG_TYPE>::CList(const CList<TYPE,ARG_TYPE> &)'
1> with
1> [
1> TYPE=int,
1> ARG_TYPE=int
1> ]
Your code as it is doesn't compile (Class should be class, Public should be public etc). What is the error message? Also you must post a simple compilable example that reproduce your error. My guess is that you didn't instantiate your static variable outside its class declaration, see
http://www.learncpp.com/cpp-tutorial/811-static-member-variables/
You may not get the error because of "Public:". Because "Public:" is not a key word it's a label. That's why "myvariable" is private by default.
Instead of "Public:" use "public:" and also replace "Static" with static.
Take a look at the definition of -
void otherfunc(CList<int,int> a)
The input parameter CList<int,int> a is passed by value, this means that when you call this function it will copy the input parameter by using CList<int,int> Copy Constructor.
But CList<int,int> does not implement a Copy Constructor, and its base class CObject define its Copy Constructor as private.
You should change the definition to -
void otherfunc(CList<int,int>& a)
I've asked a similiar question before but now I'd like to be more specific.
The problem I face is that I have an object that contains a non copyable object and when someone wants to use my interface and he does not use it well (does try to use the object's copy constructor) he will get a compilation error that will point to the object and not his actual code.
So two questions:
1. can I fix it somehow to point it to his original code line?
2. if I cannot, how can I put a static_assert that will only happen if someone actually tries to use the copy c'tor(I've tried a few but then I get them even if someone doesn't use it...)
I am adding a sample code and the compilation error in case I was not understood...
Notice the last compile error points to the ObjectHolder h. file.. while I want it to point to the main
Thanks!
* was a mistake when I replaced names.. it is in fact the code that created the compilation error.
and Let's assume I don't want to implement a private copy c'tor just to forward the disability to copy
class NonCopyableObject
{
public:
virtual ~NonCopyableObject () {}
NonCopyableObject(int i) { m_index = i;}
int m_index;
private:
NonCopyableObject(const NonCopyableObject& other) {}
};
class ObjectHolder
{
public:
virtual ~ObjectHolder ();
ObjectHolder(int i) : obj(i) {}
NonCopyableObject obj;
};
void main()
{
ObjectHolder first(1);
ObjectHolder second(first);
}
1>------ Build started: Project: tester, Configuration: Debug Win32 ------
1> main.cpp
1>d:\users\someone\documents\visual studio 2012\projects\tester\tester\objectholder.h(13): error C2248: 'NonCopyableObject::NonCopyableObject' : cannot access private member declared in class 'NonCopyableObject'
1> d:\users\someone\documents\visual studio 2012\projects\tester\tester\noncopyableobject.h(15) : see declaration of 'NonCopyableObject::NonCopyableObject'
1> d:\users\someone\documents\visual studio 2012\projects\tester\tester\noncopyableobject.h(8) : see declaration of 'NonCopyableObject'
1> This diagnostic occurred in the compiler generated function 'ObjectHolder::ObjectHolder(const ObjectHolder &)'
The error messages supplied do not reflect the code supplied.
That aside you have an error. Considering the code:
class ObjectHolder
{
public:
virtual ~ObjectHolder ();
ObjectHolder(int i) : obj(i) {}
ObjectHolder obj;
};
How is the compiler suppose to ascertain the amount of memory required for an ObjectHolder when it is recursive?
I installed visual c++ November 2012 CTP but it seems i do something wrong because i still can't use delegating constructors
I set the Platform Toolset to : Microsoft Visual C++ Compiler Nov 2012 CTP (v120_CTP_Nov2012)
This is my code:
#pragma once
#include<string>
class Hero
{
private:
long id;
std::string name;
int level;
static long currentId;
Hero(const Hero &hero); //disable copy constructor
Hero& operator =(const Hero &hero); //disable assign operator
public:
Hero();
Hero(std::string name, int level);
long GetId() const { return this->id; }
std::string GetName() const { return this->name; }
int GetLevel() const { return this->level; }
void SetName(std::string name);
void SetLevel(int level);
};
PS: Any tips regarding to c++11 and visual studio 2012 are more then welcomed. Thanks.
LE: This is the implementation file:
#include"Hero.h"
long Hero::currentId = 0;
Hero::Hero(std::string name, int level):name(name), level(level), id(++currentId)
{
}
Hero::Hero():Hero("", 0)
{
}
void Hero::SetName(const std::string &name)
{
this->name = name;
}
void Hero::SetLevel(const int &level)
{
this->level = level;
}
I get the following error message on the parameterless constructor:
"Hero" is not a nonstatic data member or base class of class "Hero"
The error message you quote is being reported by IntelliSense, which does not yet support the new C++11 language features. Note that the full text of the error message reads (emphasis mine):
IntelliSense: "Hero" is not a nonstatic data member or base class of class "Hero"
The announcement for the November CTP states (emphasis mine):
While a new Platform Toolset is provided for convenience of integrating the compiler as part of the Visual Studio 2012 build environment, the VS 2012 IDE, Intellisense, debugger, static analysis, and other tools remain essentially unchanged and do not yet provide support for these new C++11 features.
The compiler, which is updated by the November CTP, rejects the code with the following errors:
error C2511: 'void Hero::SetName(const std::string &)' : overloaded member function not found in 'Hero'
c:\jm\scratch\test.cpp(6) : see declaration of 'Hero'
error C2511: 'void Hero::SetLevel(const int &)' : overloaded member function not found in 'Hero'
c:\jm\scratch\test.cpp(6) : see declaration of 'Hero'
These errors are expected because your code is ill-formed (the parameters of SetLevel and SetName are passed by value in their inline declarations, and by reference in their definitions). When these errors are fixed, the compiler accepts your code.
class messageA {
};
class messageB {
};
template<class T>
class queue {
public:
virtual ~queue() {}
void submit(T& x) {}
};
class A : public queue<messageA>, public queue<messageB>
{
};
int main()
{
A aa;
aa.submit(messageA());
aa.submit(messageB());
}
My first thought is, the above code should be fine, as class A will contains 2 overloaded submit functions, which will accept messageA and messageB object.
However, the compiler gives me the following error :
May I know why there is an ambiguous? Isn't it is quite obvious that, for the 1st submit call, I want to call messageA version? For the 2nd submit call, I want to call messageB version?
------ Build started: Project: main, Configuration: Release Win32 ------
Compiling...
main.cpp
.\main.cpp(21) : error C2385: ambiguous access of 'submit'
could be the 'submit' in base 'queue<messageA>'
or could be the 'submit' in base 'queue<messageB>'
.\main.cpp(21) : error C3861: 'submit': identifier not found
.\main.cpp(22) : error C2385: ambiguous access of 'submit'
could be the 'submit' in base 'queue<messageA>'
or could be the 'submit' in base 'queue<messageB>'
.\main.cpp(22) : error C2664: 'queue<T>::submit' : cannot convert parameter 1 from 'messageB' to 'messageA &'
with
[
T=messageA
]
.\main.cpp(22) : error C3861: 'submit': identifier not found
I have no compiler right now, but I guess one inheritance could hide the other : The compiler will use Koenig Lookup to find the right symbol, and if I remember correctly, once the compiler find a suitable symbol (i.e., a method called "submit"), it will stop searching for others in parent and/or outer scopes.
In this case, I thought both inheriting classes would be searched for the symbol, but without your exact compiler (Visual C++ 2003 ? 2008 ? 2010 ?), I cannot guess much more.
After some thoughts, another possibility is that the compiler did find both symbols, but is unable to decide which to call (at that moment of symbol resolution, the compiler cares only for symbol name, not its exact prototype). I believe this last explanation to be the right one.
Try adding using statements in your derived classes :
class A : public queue<messageA>, public queue<messageB>
{
using queue<messageA>::submit ;
using queue<messageB>::submit ;
} ;
to bring both the submit methods directly in the A class scope.
Note, too, that your submit methods are taking messages as non-const reference, while in the constructor, your message parameters are temporaries (and thus, const r-values).
Re-writting the main as:
int main()
{
A aa;
messageA mA ;
messageA mB ;
aa.submit(mA);
aa.submit(mB);
}
could help compile (this could explain the compiler error on line 22).
Or you could change the prototype of your submit methods to accept const references instead of non-const references.
Note: Still without compiler, so trying to brain-debug your code... :-P ...
Something* smth1 = ((Base<Something> *)d)->createBase<Something>();
The above code works fine.