任何人都可以告诉c ++中动态强制转换的确切含义.我们在哪里可以使用这种动态铸造?这是在采访中向我询问的,我对这个问题一无所知:).
我很确定这是危险的代码.但是,我想检查是否有人知道究竟会出现什么问题.
假设我有这个类结构:
class A {
protected:
int a;
public:
A() { a = 0; }
int getA() { return a; }
void setA(int v) { a = v; }
};
class B: public A {
protected:
int b;
public:
B() { b = 0; }
};
Run Code Online (Sandbox Code Playgroud)
然后假设我想要一种自动扩展类的方法,如下所示:
class Base {
public:
virtual ~Base() {}
};
template <typename T>
class Test: public T, public Base {};
Run Code Online (Sandbox Code Playgroud)
我能做出的一个非常重要的保证是既Base不会也不Test会有任何其他成员变量或方法.它们本质上是空类.
(可能)危险的代码如下:
int main() { …Run Code Online (Sandbox Code Playgroud) 我错误地写了一些愚蠢的东西,令我惊讶的是.
class A
{ public:
void print()
{
std::cout << "You can't/won't see me !!!" << std::endl;
}
A* get_me_the_current_object()
{
return this;
}
};
int main()
{
A* abc = dynamic_cast<A*>(abc);
abc->print();
}
Run Code Online (Sandbox Code Playgroud)
在这里,A* abc = dynamic_cast<A*>(abc)我正在对一个未声明的指针进行dynamic_cast.但是,它有效,所以我认为上述陈述被打破为:
A* abc;
abc = dynamic_cast<A*>(abc);
Run Code Online (Sandbox Code Playgroud)
因此,它的工作原理.但是,在尝试一些更奇怪的场景时,例如:
A* abc;
abc->print();
Run Code Online (Sandbox Code Playgroud)
并进一步
A* abc = abc->get_me_the_current_object();
abc->print();
Run Code Online (Sandbox Code Playgroud)
我惊呆了,看着这些例子是如何运作的,并且映射已经完成.
有人可以详细说明这些是如何工作的吗?提前致谢.
我有以下内容:
class A { ... };
class B : public A { ... };
// ...
B b;
const A& aref(b);
// ...
const B& bref(aref);
Run Code Online (Sandbox Code Playgroud)
当我编译时,我得到:
no suitable user-defined conversion from "const A" to "const B" exists
Run Code Online (Sandbox Code Playgroud)
现在,如果这些是指针而不是引用,我会使用
bptr = dynamic_cast<B*>(aptr);
Run Code Online (Sandbox Code Playgroud)
但参考文献没有.我该怎么办?切换到指针?别的什么?
在我正在工作的项目中,我注意到动态向下转换失败了.快速代码检查证实,特定对象实际上从不属于那种类型.但是,我看到其他开发人员通过应用静态强制转换强制执行此非常相同的强制转换.
在我看来,这是一种危险的方法,非常脆弱,如下例所示.这通常不是一个糟糕的编程习惯吗?
class Base
{
public:
Base(){ m_p = 0; }
protected:
int m_p;
};
class Derived: public Base
{
public:
Derived(){ m_arr = new int[1]; }
void Add_A() { m_p += 2; }
void Add_B() { m_arr[0] += 3; }
private:
int* m_arr;
};
Base* parent = new Base();
// obviously fails -> c_d is null
Derived* c_d = dynamic_cast<Derived*>(parent);
Derived* c_s = static_cast<Derived*>(parent);
c_s->Add_A(); // works
c_s->Add_B(); // crashes, since m_arr does not exist.
Run Code Online (Sandbox Code Playgroud) 当我尝试将基类转换为派生类时,我收到错误.我想访问我放在组件向量中的派生类.
//基础和派生
class Component
{
public:
Component();
virtual ~Component();
private:
};
class Material:public Component{...};
Run Code Online (Sandbox Code Playgroud)
//在主要
int textureID = gameScene.gameObjects[0].getComponent<Material>()->texture;
Run Code Online (Sandbox Code Playgroud)
//游戏对象
#pragma once
#include <vector>
#include "Component.h"
class GameObject:public Component
{
public:
GameObject();
GameObject(int otherAssetID);
~GameObject();
int assetID;
std::vector<Component> components;
void addComponent(Component otherComponent);
void deleteComponent(Component otherComponent);
template <class T>
T* getComponent() {
for (int i = 0; i < components.size(); i++)
{
if (dynamic_cast<T*>(components[i]) != nullptr)
{
T *test = dynamic_cast<T*>(components[i]);
return test;
}
}
return nullptr;
}
private:
};
Run Code Online (Sandbox Code Playgroud) 我试图找出代码中编译错误的原因:
class A
{
public:
virtual ~A(){}
};
class B: public A
{
public:
virtual ~B(){}
};
class D: public B
{
public:
virtual ~D(){}
};
template <class X, class Y>
X* fun(X* p){return dynamic_cast<Y*>(p);}
int main()
{
A* q = dynamic_cast<B*>(new D());
A* p = fun<D,B>(new D());
}
Run Code Online (Sandbox Code Playgroud)
对我来说,似乎指针q和p应该指向相同的类型但是对于p我收到编译器错误,说"无效转换从'B*'到'D*'".我唯一没有得到错误的是当我以B的子类为D(因此p是空指针)的方式更改类时.谁能帮我理解为什么会这样?
以下代码编译并正常工作:
#include<iostream>
class Base {
protected:
int _a;
public:
virtual ~Base()=default;
Base(int a) : _a{a} {};
int getit() const { return _a; }
};
class Derived : public Base {
public:
Derived(int a) : Base{a} {};
int get2() const { return 2*this->_a; }
};
int main() {
Base D{2};
auto* ptr = &D;
auto* ptr2 = static_cast<Derived*>(ptr);
std::cout << ptr2->get2() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
输出
4
Run Code Online (Sandbox Code Playgroud)
如果我改变static_cast了dynamic_cast它出现segfaults。
我的问题:
使用static_cast强制转换为不添加任何数据成员的派生类是否安全?
class A
{
};
class B:public A
{
};
int main()
{
A a;
B b;
A *ap = &b;
B *bp = dynamic_cast<B*>(ap);
if(bp!= NULL)
cout<<"Pass"<<endl;
else
cout<<"Fail"<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果你想进行动态演员,为什么A类应该是虚拟的呢?
这是我的班级:
class AComponent : public nts::IComponent
{
public:
AComponent(const size_t &maxInputs, const size_t &maxOutputs, const size_t &value);
AComponent(nts::AComponent &);
virtual ~AComponent();
virtual nts::Tristate Compute(size_t pin_num_this = 1);
virtual void SetLink(size_t pin_num_this,
nts::IComponent &component,
size_t pin_num_target);
void setComponent(const size_t &components, nts::Tristate &state);
virtual void Dump(void) const;
nts::Tristate &getComponent(const size_t &pin);
protected:
std::vector <nts::Tristate *> _components;
size_t _maxInputs;
size_t _maxOutputs;
};
Run Code Online (Sandbox Code Playgroud)
当我尝试拨打这一行时:
this->_components[pin_num_this] =
&static_cast<nts::AComponent>(component).getComponent(pin_num_target);
Run Code Online (Sandbox Code Playgroud)
我发生了以下编译错误:
sources/AComponant.cpp:33:76: error: no matching function for call to ‘nts::AComponent::AComponent(nts::IComponent&)’
this->_components[pin_num_this] = &static_cast<nts::AComponent>(component).getComponent(pin_num_target);
Run Code Online (Sandbox Code Playgroud)
如果我实现构造函数,它就在这里.问题是,我不想操纵IComponent,我想操纵AComponent …
c++ ×10
dynamic-cast ×10
polymorphism ×4
static-cast ×4
inheritance ×2
downcast ×1
game-engine ×1
oop ×1
reference ×1
templates ×1
this ×1
virtual ×1