我从"更有效的C++"一书中复制了以下文本.
第31项:使函数虚拟化为多个对象.
class GameObject { ... };
class SpaceShip: public GameObject { ... };
class SpaceStation: public GameObject { ... };
class Asteroid: public GameObject { ... };
Run Code Online (Sandbox Code Playgroud)
最常见的双重调度方法通过if-then-elses链将我们带回到虚拟函数仿真的无情世界.在这个苛刻的世界中,我们首先发现了otherObject的真实类型,然后我们针对所有可能性测试它:
void SpaceShip::collide(GameObject& otherObject)
{
const type_info& objectType = typeid(otherObject);
if (objectType == typeid(SpaceShip)) {
SpaceShip& ss = static_cast<SpaceShip&>(otherObject);
process a SpaceShip-SpaceShip collision;
}
else if (objectType == typeid(SpaceStation)) {
SpaceStation& ss =
static_cast<SpaceStation&>(otherObject);
process a SpaceShip-SpaceStation collision;
}
...
}
Run Code Online (Sandbox Code Playgroud)
这是一个问题:
Q1>为什么我们在这里使用static_cast而不是明显的dynamic_cast?
Q2>在这种情况下它们是否相同?
谢谢
// 更新 //
事实上,我对问题2更感兴趣.
例如,
class base …Run Code Online (Sandbox Code Playgroud) 我想调用函数,它会更改小部件内的文本。
有一个virtual函数NativeConstruct,它会自动调用。它会更改小部件的文本,但我需要调用函数F1并向其发送我想要显示的文本。但是当我调用它时,变量Name是nullptr. 由于某种原因nullptr,当程序调用NativeConstruct.
Name 是我的文本变量,我想改变dialogBottom 是具有此变量的小部件的名称已编辑
UAccessWidgetFromCpp* AccessWidgetFromCpp
= CreateWidget<UAccessWidgetFromCpp>(
GetWorld()->GetFirstPlayerController(), UAccessWidgetFromCpp::StaticClass()
);
if (AccessWidgetFromCpp)
{
AccessWidgetFromCpp->F1("222");
widgetDialogBottomInstance->AddToViewport();
}
UCLASS()
class HOME_API UAccessWidgetFromCpp : public UUserWidget
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UTextBlock* Name = nullptr;
UFUNCTION()
void F1(FString text);
};
void UAccessWidgetFromCpp::F1(FString text)
{
if (auto widget = dynamic_cast<UTextBlock*>(GetWidgetFromName(TEXT("Name"))))
{
Name = widget;
Name->SetText(FText::FromString(text));
}
}
Run Code Online (Sandbox Code Playgroud)
在 OOP 概念中,RTTI(运行时类型信息)是也用于静态转换还是仅用于动态转换?
如果它特定于动态转换,那么请证明您的答案是合理的,并请解释为什么没有用于 static_casting 的 RTTI。
使用 RTTI 进行向下转换有什么意义?
可能重复:
生成随机枚举
可以说我有以下内容:
enum Color {
RED, GREEN, BLUE
};
Color foo;
Run Code Online (Sandbox Code Playgroud)
我想要做的是随机地将foo分配给一种颜色.最直接的方式是:
int r = rand() % 3;
if (r == 0)
{
foo = RED;
}
else if (r == 1)
{
foo = GREEN;
}
else
{
foo = BLUE;
}
Run Code Online (Sandbox Code Playgroud)
我想知道是否有更清洁的方法.我尝试过(并且失败了)以下内容:
foo = rand() % 3; //Compiler doesn't like this because foo should be a Color not an int
foo = Color[rand() % 3] //I thought this was worth a shot. Clearly didn't work.
Run Code Online (Sandbox Code Playgroud)
如果你们知道任何更好的方式不涉及3 if语句,请告诉我.谢谢.
从转换Base*到Derived*始终允许吗?从转换const Base*到const Derived*始终允许吗?
我正在使用Qt QSharedPointers.我有一个QSharedPointer Base对象,我想将QSharedPointer转换为Derived对象.我事先检查了指针的类型Derived.
是否有可能获得100%的成功机会
static_cast<QSP<Derived>>dynamic_cast<QSP<Derived>>QSP<Derived>(my_base_pointer)?
例如,对于直接转换:
QSP<Derived> inpf = QSP<Derived>(my_base_pointer) ;
Run Code Online (Sandbox Code Playgroud)
我有错误
Error 1 error C2440: 'initializing' : cannot convert from 'Base *' to 'Derived *'
Run Code Online (Sandbox Code Playgroud)
与my_base_pointer类型const QSP<Base>.
是因为常数吗?我应该const_cast吗?我认为constness不是根本原因,因为如果我
const QSP<Derived> inpf = static_cast<const QSP<Derived>>(my_base_pointer);
Run Code Online (Sandbox Code Playgroud)
发生同样的错误.
我的主要职能有以下几行。
BlackScholesPricer* option = new EuropeanCallOption(105, 100, 0.5, 0.1, 0.36, 0);
PricingUtil::mesh_pricer<EuropeanCallOption>(option, 105, 150, 5);
Run Code Online (Sandbox Code Playgroud)
这是有问题的功能。
template <typename OptionType>
std::vector<double> PricingUtil::mesh_pricer(BlackScholesPricer* option,
std::size_t lower_bound, std::size_t upper_bound, std::size_t mesh_size) {
OptionType financial_instrument(*option);
std::vector<double> generated_prices;
for (std::size_t price = lower_bound; price <= upper_bound; price += mesh_size) {
financial_instrument.asset_price(price);
generated_prices.push_back(financial_instrument.price());
}
return generated_prices;
}
Run Code Online (Sandbox Code Playgroud)
我想将派生类BlackScholesPricer传递给该函数,但是我不想修改传递给该函数的对象,因此我试图创建它的副本。我收到一条错误消息,指出不能将BlackScholes *类型的对象转换为const EuropeanCallOption&(这是我想的复制构造函数)。
解决问题的最有效方法是什么,或者甚至更好的方法是,除了我以外,在这种情况下采取的最佳方法是什么?
我有一个简单的整数向量,只有4个值.我想循环遍历向量,为每个值分配0或1.我希望它随机到每次都不同的程度.
我认为以下就足够了:
for (int i = 0; i < (int)numberVect.size(); i++)
{
numberVect[i] = rand() % 2;
}
Run Code Online (Sandbox Code Playgroud)
但是,我发现每次关闭并重新打开程序时,都会分配完全相同的值.
所以第一次通过它将是1,0,0,0,然后如果我再次运行循环而不关闭程序它将是0,1,0,1.这看起来很完美.
但是,关闭程序并重新启动后,我会发现第一个序列将再次为1,0,0,0,第二个序列将再次为0,1,0,1.
另外,我有关于这个问题的第二个问题:
你能建议一种方法来确保向量中的至少一个值是1吗?同时仍然允许随机生成无缝地工作?
非常感谢,我希望你们可以提供帮助:D
考虑以下代码:
#include <iostream>
using namespace std;
class Base{
int i;
public:
virtual bool baseTrue() {return true;}
Base(int i) {this->i=i;}
int get_i() {return i;}
};
class Derived : public Base{
int j;
public:
Derived(int i,int j) : Base(i) {this->j=j;}
int get_j() {return j;}
};
int main()
{
Base *bp;
Derived *pd,DOb(5,10);
bp = &DOb;
//We are trying to cast base class pointer to derived class pointer
cout << bp->get_i() << endl;
cout << ((Derived *)bp)->get_j() << endl;**//HERE1**
pd=dynamic_cast<Derived*> (bp); **//HERE2**
// …Run Code Online (Sandbox Code Playgroud) 在下面的一个例子中,我想知道func带有错误类型参数的调用 - vptr应该用int指针调用.
void func(int * ptr){
}
int main(){
void * vptr;
func(vptr);
}
Run Code Online (Sandbox Code Playgroud)
即使有墙式选项,海湾合作委员会也不会警告这类警告.在gcc中还有其他任何选项,或其他编程技巧来找出那些不良的代码方式.除此之外,在cpp怎么样?
编辑:VTT回答这在C中有效,但在C++中无效,没有其他类似的演员关键字static_cast(详见其他帖子).
任何人都可以告诉c ++中动态强制转换的确切含义.我们在哪里可以使用这种动态铸造?这是在采访中向我询问的,我对这个问题一无所知:).
我需要对我在这里阅读的特定段落做一些解释.
所以在第一个例子中:
// pointers to base class
#include <iostream>
using namespace std;
class CPolygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b; }
};
class CRectangle: public CPolygon {
public:
int area ()
{ return (width * height); }
};
class CTriangle: public CPolygon {
public:
int area ()
{ return (width * height / 2); }
};
int main () {
CRectangle rect;
CTriangle trgl;
CPolygon * ppoly1 = ▭ …Run Code Online (Sandbox Code Playgroud)