我有以下代码片段
class base
{
public:
virtual void MyMethod()
{
std::cout << "Base MyMethod" << "\n";
}
};
class der : public base
{
public:
virtual void MyMethod()
{
std::cout << "Derived MyMethod" << "\n";
}
};
void foo(base* b)
{
der* d = static_cast<der*>(b);
d->MyMethod();
}
int main()
{
base* b = new der();
foo(b);
}
Run Code Online (Sandbox Code Playgroud)
现在我的问题是为什么 static_Cast 在这里工作。我读到 static_casts 不能通过多态类型进行转换。那么为什么上面的例子有效 - 我在这里遗漏了什么吗?我期望动态转换只能解决这样的问题,因为它们应该与多态类型一起使用?谁能举一个例子,静态转换会失败而动态转换会通过?
这个类是多态的.为什么两者都打印相同的输出?
class A
{
public:
virtual void P(){ cout << "A" << endl; }
};
class B : public A
{
public:
void P()override{
cout << "B" << endl;
}
B(){ cout << "Created B" << endl; s = "Created by B"; }
string s;
};
Run Code Online (Sandbox Code Playgroud)
主要:变体1:
A* a = new B(); // Created B
B* b = static_cast<B*>(a);
b->P(); B
cout<<b->s<<endl; // Created by B
Run Code Online (Sandbox Code Playgroud)
变种2:
A* a = new B();
B* b = dynamic_cast<B*>(a);
if (b){
b->P();
cout …Run Code Online (Sandbox Code Playgroud) 我目前正在研究一些看起来很奇怪的第三方 C++ 代码(我从 C++11 开始)。让我感到困惑的许多事情之一是static_castfromNULL到某种指针类型的许多实例:
SomeClass* someClassPtr = static_cast<SomeClass*>(NULL);
Run Code Online (Sandbox Code Playgroud)
我知道你可以将指针从基类指针转换为派生类指针,但这里绝对没有继承。据我所知,这应该足够了:
SomeClass* someClassPtr = NULL;
Run Code Online (Sandbox Code Playgroud)
但是这段代码中唯一NULL没有被强制转换为特定指针类型的情况是向量和其他容器中的指针:
SomeOtherClass.vecOfSomeClassPtr[i] = NULL;
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:
nullptr吗?NULL在处理继承时,除了向下/向上转换之外,其他事情是否需要强制转换?如果到目前为止我还没有弄错:
我首先替换了static_cast<type*>(NULL)withNULL和后来的所有实例nullptr,看看这是否会破坏任何东西:不。编译器没有抗议,程序似乎仍然按预期工作。但我知道指针可能是棘手的小混蛋,所以:
nullptr我可能错过了使用的哪些陷阱?PS:是的,我确实使用了搜索,是的,我确实在 C 代码上找到了类似的问题。但这是 C++ 代码,我想确定地知道,而不仅仅是假设某些东西。
(我知道这与这里的其他一些问题非常相似,但我还没有找到任何具体的语言律师回答这个精确的细节。大多数接近重复的人只是问他们是否应该使用static_cast功能风格强制转换(答案:是),或者C 风格static_cast强制转换之间的区别。)
在 C++ 中,以下两个强制转换看起来非常相似:
template<class T, class U> auto convert1(U&& u) {
return T( std::forward<U>(u) );
}
template<class T, class U> auto convert2(U&& u) {
return static_cast<T>( std::forward<U>(u) );
}
Run Code Online (Sandbox Code Playgroud)
任何类型有什么区别吗T?U或者它们的效果 100% 相同吗?
如果它们不同,我会很欣赏标准库中与细微差异相关的地方的一些示例。(我的意思std::make_shared<T>(args...)是如何指定如何构造其对象,T(args...)而不是因为和那里T{args...}之间的细微差别。)T()T{}
我用的时候static_cast:
const C* cObj; // C is a user-defined class
void* obj = static_cast<void*>(cObj);
Run Code Online (Sandbox Code Playgroud)
我收到错误:
转换失去限定符
但是当我使用C风格的演员表时,它可以工作:
const C* cObj;
void* obj = (void*)cObj;
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
通过C++样式转换来实现它的正确方法是什么?
我正在写一个可移动的QScopedPointer;基本上std::unique_pointer有一些额外的访问器。我在访问 C++11 兼容编译器之前就开始了它,但现在我决心把它做好(即使我在重新发明轮子)。
让我们调用我的智能指针MyUniquePointer。
我需要知道 type 是否U *可以T *通过 a转换为 type static_cast,特别是:
template<class T, class Cleanup>
class MyUniquePointer
{
...
template<class U, class CleanupU, class = std::enable_if_t<detail::is_safely_castable<U, T>()>
MyUniquePointer(MyUniquePointer<U, CleanupU> && other) noexcept
: d(static_cast<T *>(other.release()))
{}
...
Run Code Online (Sandbox Code Playgroud)
我的第一次尝试是static_cast在 an 内部使用enable_if,但您不能使用 的地址std::declval()来获取static_cast!
如果指向的指针U可以static_cast指向T使用模板魔术的指针,有没有办法使用测试?
基于cppreference和这个答案,我尝试创建一个模板测试来模拟 static_cast 何时合法,如果向下转换,则安全 …
我试图理解为什么使用指针从基类到派生类的转换编译得很好,但使用非指针对象进行转换会产生错误 C2440。
ThreadedMessage下面我有一个由 class 继承的基类GPSMessage。
struct ThreadedMessage
{
ThreadedMessage()
: m_Type(0), m_ID(0)
{ }
ThreadedMessage(uint Type, uint ID = 0) :
m_Type(Type), m_ID(ID)
{ }
uint m_Type;
uint m_ID;
};
struct GPSMessage : public ThreadedMessage
{
GPSMessage()
: ThreadedMessage()
{ }
GPSMessage(double lat, double lon)
: ThreadedMessage(1), m_lat(lat), m_lon(lon)
{ }
double m_lat;
double m_lon;
};
Run Code Online (Sandbox Code Playgroud)
我试图myFunction从基类转换为派生类。
void myFunction(const ThreadedMessage& msg)
{
const GPSMessage* message = static_cast<const GPSMessage*>(&msg); // Compiles fine
const GPSMessage message1 = …Run Code Online (Sandbox Code Playgroud) 我有一段代码返回给定数字的某些位的值(我也使用 static_cast 将枚举类计算为一个数字)。
template<typename Type>
bool get_bits(Type input, uint8_t offset, uint8_t n, Type* destination)
{
if (offset + n> sizeof(Type) * 8)
return false;
Type bitmask = 0;
for (int i = 0; i < n; ++i)
bitmask |= (1 << i);
*destination = static_cast<Type>(input >> offset & bitmask);
return true;
}
Run Code Online (Sandbox Code Playgroud)
该函数试图返回的值n的位input由开始offset。它适用于整数类型,但是当我尝试将它与枚举类一起使用时,编译失败。我尝试使用std::underlying_type然后它适用于枚举类但不适用于整数类型:|。我怎样才能将它用于他们两个?我的意思是,如果类型是枚举类,我想将输入转换为它的underlying_type,执行一些按位运算,然后将结果(使用static_cast)存储到目标。但是对于没有underlying_type 的整数类型,不应该进行这些转换。
鉴于以下条件:
struct A
{
int a;
};
struct B
{
int b;
};
int main()
{
A a {1};
A* p = &a;
Run Code Online (Sandbox Code Playgroud)
使用static_cast和使用reinterpret_castvia 进行铸造void*会产生相同的结果吗?即以下表达式之间有什么区别吗?
static_cast <A*> ( static_cast <void*> (p) );
reinterpret_cast <A*> ( reinterpret_cast <void*> (p) );
Run Code Online (Sandbox Code Playgroud)
如果我们投指针到一个类的指针到其他课程,static_cast并与reinterpret_cast?这两个运营商之间有什么区别吗?下列表达式是否相同?
static_cast <B*> ( static_cast <void*> (p) );
reinterpret_cast <B*> ( reinterpret_cast <void*> (p) );
reinterpret_cast <B*> ( p );
Run Code Online (Sandbox Code Playgroud)
我可以B*在此之后使用指针来访问b成员吗?
我试图将GMP数字库与特征矩阵库一起使用.我尝试实例化模板:
Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
Run Code Online (Sandbox Code Playgroud)
同
Matrix<mpz_class, 3, 3> matrix;
Run Code Online (Sandbox Code Playgroud)
其中mpz_class是GMP库中的数字类.
我收到编译器错误:
/usr/include/eigen3/Eigen/src/Core/MathFunctions.h:409: error:
invalid static_cast from
type ‘const __gmp_expr<__mpz_struct [1], __mpz_struct [1]>’
to type ‘int’
Run Code Online (Sandbox Code Playgroud)
当我检查Eigen库的源代码时,我发现问题是mpz_class在这个模板中不能是static_cast -ed到int:
template<typename OldType, typename NewType>
struct cast_impl
{
static inline NewType run(const OldType& x)
{
return static_cast<NewType>(x);
}
};
Run Code Online (Sandbox Code Playgroud)
我该如何绕过这个问题?我知道如何在运行时将mpz_class转换为int,但它必须由编译器完成,因为static_cast是编译时.
static-cast ×10
c++ ×9
casting ×2
sfinae ×2
c++11 ×1
c++14 ×1
dynamic-cast ×1
eigen ×1
enum-class ×1
gmp ×1
null ×1
nullptr ×1
pointers ×1
polymorphism ×1
templates ×1