如果我有这个类结构:
class A
{
public:
int a;
void funcA(){a = 0;}
};
class B
{
public:
int b;
void funcB(){b = 0;}
};
class C: public A, public B
{
public:
int c;
void funcC(){c = 0;}
};
Run Code Online (Sandbox Code Playgroud)
为什么我可以执行此演员表?
A* pA = new A;
C* pC = static_cast<C*> (pA);
B* pB = static_cast<B*> (pC);
pB->funcB();
Run Code Online (Sandbox Code Playgroud)
A和B是无关的,不是吗?
请考虑以下示例代码.
#include <iostream>
using namespace std;
class base
{
public:
void func()
{
cout << "base::func()" << endl;
}
};
class derived : public base
{
public:
void func()
{
cout << "derived::func()" << endl;
}
};
void dummy(base *bptr)
{
derived *dptr = static_cast<derived*> (bptr);
dptr->func();
}
int main()
{
base bob1;
derived dob1;
dummy(&dob1); //Line1
dummy(&bob1); //Line2
}
Run Code Online (Sandbox Code Playgroud)
在Line1中,我将派生类对象的地址传递给函数dummy,该函数接受指向基类对象的指针.所以static_cast在功能上dummy是安全的.
在Line2中,我将基类对象的地址传递给函数.所以static_cast在功能上dummy是不安全的.
但是当我执行代码时,程序运行正常.我想,通过这个词not safe,程序应该在运行时崩溃.但没有发生崩溃.
这是我得到的输出.
derived::func()
derived::func()
Run Code Online (Sandbox Code Playgroud)
程序在运行时没有崩溃的原因是什么?
我有一个类型定义typedef vector<Object*> ObjList;我也有一个功能vector<BigObject*>* ObjectBox::getBigObjectList();.BigObject从...开始Object
我想要做的是得到一个vector<BigObject*>*来自getBigObjectList()并将其转换为vector<Object*>*,这是一个向上铸造,而这个类型被定义为ObjList,所以我基本上是想以CONVER变成一只ObjList类型
我试过两种方式,第一种是
ObjList *normalObjectList = (ObjList*) box->getBigObjectList();
Run Code Online (Sandbox Code Playgroud)
这个编译,我从这篇文章中读到(什么时候应该使用static_cast,dynamic_cast,const_cast和reinterpret_cast?),这说C风格的转换很少需要,因为它可以发展成为reinterpret-cast
然后我尝试使用static_cast,但我收到一个错误,说无效的类型转换
ObjList *normalObjectList = static_cast<ObjList*> (box->ClipObjectInRect());
Run Code Online (Sandbox Code Playgroud)
这也不行
ObjList *normalObjectList = static_cast<vector<Object*>*> (box->ClipObjectInRect());
Run Code Online (Sandbox Code Playgroud)
为什么这不起作用?这是因为static_cast只能用于投射直接类(如Object自身)而不是嵌套类(我只是在这里猜测)?在这种情况下我该怎么办?
我试图将接口对象static_cast成为继承该接口的派生类的对象.我收到了一个错误
'static_cast':无法从'IInherit*'转换为'cDerived*'
派生类和接口具有以下格式.
class cDerived: public IInherit
{
Repo* p_Repos;
public:
cDerived(Repo* pRepos)
{
p_Repos = pRepos;
}
Repo* GetRepo()
{
return p_Repos;
}
void doAction(ITok*& pTc)
{
///some logic
}
}
class IInherit
{
public:
virtual ~IInherit() {}
virtual void doAction(ITok*& pTc)=0;
};
Run Code Online (Sandbox Code Playgroud)
我vector<IInherit*>通过getInherit()方法在代码中可以访问一个对象,这样getInherit()[0]的类型是cDerived*我正在使用表达式执行静态转换:
Repo* pRep= static_cast<cDerived*>(getInherit()[0])->GetRepo();
Run Code Online (Sandbox Code Playgroud)
我不确定static_cast是否可以作为接口对象.有没有其他方法可以执行此演员表?
我最近有一种情况,我不得不使用static_cast将父类强制转换为子类,因为我知道对象实例是那个子类.我基于if条件知道这一点.
像这样的东西:
parent* foo;
child* bar;
if(foo is instance of child class)
bar = static_cast<child*>(foo)
Run Code Online (Sandbox Code Playgroud)
我的问题是:为什么static_cast总是需要指针?当我用非指针变量尝试它时,这不起作用.一个例外似乎是原始数据类型.
这是因为每个指针都可以转换为void*吗?这是static_cast的工作原理吗?
编辑:我忘了提到它适用于参考.因此,目前陷害的问题是错误的.重新定义问题"为什么static_cast需要指针或引用?"
我听说静电铸造是一种更安全的铸造方式.
可以说我有以下代码:
int nValue = 48;
char ch = nValue;
Run Code Online (Sandbox Code Playgroud)
这是隐式投射.但是将4个字节更改为1个字节是不安全的.如果我将此代码更改为:
int nValue = 48;
char ch = static_cast<char>(nValue);
Run Code Online (Sandbox Code Playgroud)
这会更安全.为什么?是什么让它更安全?它仍然将4个字节更改为1个字节.
我将在"C++编程语言"中查看以下示例代码:
typedef int (*CFT) (const void*, const void*);
void ssort(void* base, size_t n, size_t sz, CFT cmp) {
for (int gap = n / 2; 0 < gap; gap /= 2) {
for (int i = gap; i < n; i++) {
for (int j = i - gap; 0 <= j; j -= gap) {
char* b = static_cast<char*>(base);
char* pj = b + j * sz;
char* pig = b + (j + gap) * sz;
if (cmp(pig, …Run Code Online (Sandbox Code Playgroud) 我有一个问题,它不想使用static_cast <>进行强制转换.它能是什么?
void myCompare(const void *str)
{
const char *ca = *(static_cast<const char**>(str)); //error
const char *a = *(const char **)str; //ok
}
Run Code Online (Sandbox Code Playgroud) 我想这样做
static_cast<IntrusivePtr<B>>(IntrusivePtr<A>)
Run Code Online (Sandbox Code Playgroud)
其中B公开来自A但是这给出了错误
invalid conversion from A* to B*
Run Code Online (Sandbox Code Playgroud)
任何人都可以向我解释这里的问题吗?我可以通过这样做来解决它
static_cast<B*>(IntrusivePtr<A>.get())
Run Code Online (Sandbox Code Playgroud)
理论上这正是上述错误消息所说的内容是不允许的.这是GCC 4.4.7
考虑以下简单程序:
#include <iostream>
void foo() { }
int main() {
std::cout<<static_cast<void*>(foo);
}
Run Code Online (Sandbox Code Playgroud)
它编译罚款VC++,但g++与clang++给编译错误.
在这里看现场演示(VC++)
在这里看现场演示(clang++)
在这里看现场演示(g++)
诊断由g++&给出clang++:
source_file.cpp: In function ‘int main()’:
source_file.cpp:4:38: error: invalid static_cast from type ‘void()’ to type ‘void*’
std::cout<<static_cast<void*>(foo);
^
Run Code Online (Sandbox Code Playgroud)
那么,问题是根据C++标准,哪个编译器就在这里?我认为,行为g++和clang++正确这里.我知道我应该reinterpret_cast在这里使用而不是static_cast.这是VC++编译器中的错误吗?如果答案取决于C++的具体标准,那么我也很想知道它.
c++ ×10
static-cast ×10
casting ×4
clang++ ×1
inheritance ×1
pointers ×1
string ×1
typedef ×1
visual-c++ ×1