例如,在
unique_ptr<Derived> = new deriv;
std::vector<unique_ptr<Base>>.push_back(std::move(deriv));
Run Code Online (Sandbox Code Playgroud)
将派生切片打字unique_ptr<Base>?
如果我们使用多重继承,切片将使父对象的地址与地址到叶对象不同:
struct X {int x};
struct Y {int y};
struct Z : X, Y {int z};
Run Code Online (Sandbox Code Playgroud)
因此,如果我们有一个Z对象z,它的地址&z将不与Y其父对象的地址重合:static_cast<Y*>(&z)高出四个字节&z.
好处static_cast是,它是静态的,因此不会占用运行时间(相比之下dynamic_cast).但是,如果我们有一个Z*指向的内容0,那么每次转换为父级都应该并且确实产生一个空指针.为什么这样做以及如何实施?这是否意味着每一个都static_cast引入了分支指令?
我想复制Foo对象类型的向量,但对象可以是几种不同的Foo派生类型.我无法弄清楚如何复制而不切片.这是我的玩具代码
#include "stdafx.h"
#include <memory>
#include <vector>
#include <string>
#include <iostream>
class Foo
{
public:
Foo() { m_x = "abc"; }
Foo( const Foo &other ) { m_x = other.m_x; }
virtual std::string ToString() { return m_x; }
std::string m_x;
};
class FooDerivedA : public Foo
{
public:
FooDerivedA() : Foo() { m_y = 123; }
std::string ToString() { return m_x + ", " + std::to_string( m_y ); }
int m_y;
};
class FooDerivedB : public Foo
{
public:
FooDerivedB() …Run Code Online (Sandbox Code Playgroud) 打印出以下代码
Derived
Base
Base
Run Code Online (Sandbox Code Playgroud)
但我需要将每个Derived对象放入User :: items,调用自己的print函数,而不是基类.我可以在不使用指针的情况下实现吗?如果不可能,我应该如何编写逐个删除User :: items并释放内存的函数,以免出现任何内存泄漏?
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Base{
public:
virtual void print(){ cout << "Base" << endl;}
};
class Derived: public Base{
public:
void print(){ cout << "Derived" << endl;}
};
class User{
public:
vector<Base> items;
void add_item( Base& item ){
item.print();
items.push_back( item );
items.back().print();
}
};
void fill_items( User& u ){
Derived d;
u.add_item( d );
}
int main(){
User u;
fill_items( u );
u.items[0].print();
}
Run Code Online (Sandbox Code Playgroud) 我无法理解导致C++和C#之间差异的原因.
首先,我们有一个基类包含虚函数的示例.
class Base
{
protected:
int super;
public:
virtual int f() = 0;
};
class Derived : public Base
{
public:
int extraA;
int f(){ return 1; }
};
int main()
{
Derived *d = new Derived();
std::vector<Base*> v;
v.push_back(d);
for(int i=0; i < v.size() ;i++)
{
// Output "Derived"
std::cout << typeid(*v[i]).name() << std::endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,这个输出是"派生的".
如果我们删除f(),这将不再有效.输出是"Base".例:
class Base
{
protected:
int super;
};
class Derived : public Base
{
public:
int extraA;
};
int …Run Code Online (Sandbox Code Playgroud) 前几天我遇到了一个实例,我有一个函数,它指向一个基类型,然后我需要向上转换为派生类型以访问一些额外的功能.然而,dynamic_cast失败了,这很奇怪,因为我的类型肯定继承了基类型.
为了了解正在发生的事情的底部,我创建了以下测试程序,我认为它复制了我所看到的:
void cast(TestClass *baseType)
{
if (dynamic_cast<Derived *>(baseType))
TRACE("cast was sucessful");
else
TRACE("cast failed");
}
int main(int argc, char *argv[])
{
Derived *test1 = new Derived();
TestClass *test2 = new TestClass();
TestClass test3;
test1->identify(); // prints: this is a Derived class
test2->identify(); // prints: this is a TestClass
cast(test1); // succesful
cast(test2); // fail - expected
// reassign test2 to test1
test2 = test1;
test2->identify(); // prints: this is a Derived class
cast(test2); // succesful
// the …Run Code Online (Sandbox Code Playgroud) 所以我有一个载满我游戏所有物体的载体; 玩家对象,敌人对象,墙壁等等......向量中的所有东西都是子对象Framework,所以我创建了向量类型,Framework因为这是它们与通用数据类型最接近的东西.
问题是它没有从它存储的对象运行重写的函数.所以我用谷歌搜索它,显然我通过将它们存储为对象切片Framework.那么我的问题是,如何将所有这些对象存储在一个列表中?
仅供参考,这是调用假定被覆盖的函数的地方.
for (vector<Framework>::iterator num = gameObjects.begin(); num != gameObjects.end(); ++num)
{
//The current thing
Framework currentObject = *num;
currentObject.frameEvent();
currentObject.frameEndEvent();
currentObject.drawEvent();
}
Run Code Online (Sandbox Code Playgroud)
提前致谢.
在一次采访中,我被问到为什么按价值捕获异常可能是一个问题,我回答说这会导致对象切片.这就是我在互联网上找到的,例如:https://www.viva64.com/en/w/v746/
但是现在我正在尝试进行实验,但是在按值捕获时我找不到切片的示例.切片的常规场景(不是例外)是这样的:
Derived d1;
Derived d2;
Base& b1 = d1;
Base& b2 = d2;
b1 = b2;
Run Code Online (Sandbox Code Playgroud)
在最后一行中调用Base的赋值运算符,它只复制Derived对象的Base部分.因此,b1的基础部分是从d2复制的,而b1的派生部分是从d2复制的.坏.
但是,当按价值捕获异常时,这怎么会发生?
我尝试了这个代码(同时使用:g ++和Sun CC编译器):
struct Base
{
virtual void print() const
{
cout << "{ Base: " << m << " }" << endl;
}
Base(int _m = 0) : m(_m) {}
int m;
};
struct Derived : Base
{
Derived(int _m = 0, int _n = 0) : Base(_m), n(_n) {}
void print() const
{
cout << "{ …Run Code Online (Sandbox Code Playgroud) 假设我有一个A具有 type 成员的类int。我有一个类B,它是A.
B旨在将成员初始化为某种状态,没有其他目的。
#include <string>
#include <iostream>
struct A {
int someInt;
A() : someInt(33){}
};
struct B : public A {
B() {
someInt = 4;
}
};
int main() {
A a = A();
A b = B();
std::cout<< a.someInt << std::endl;
std::cout << b.someInt << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
请注意我如何使用A b = B()对象切片应该发生的地方。但是,由于B没有向 中添加任何内容 A,它是否是使用A不同构造函数参数(或创建 的任何其他形式的实例A)的有效替代方法?
编辑:背景是我有一个具有一些复杂设置的类。将初始化放在单独的子类中比编写构造函数、工厂或构建器要容易得多。
c++ ×10
object-slicing ×10
c# ×2
casting ×1
class ×1
dynamic ×1
dynamic-cast ×1
exception ×1
inheritance ×1
java ×1
null ×1
polymorphism ×1
reference ×1
rethrow ×1
static-cast ×1
std ×1
types ×1
vector ×1