【发布时间】:2021-11-28 12:42:26
【问题描述】:
我正在使用一个现有的C++,看起来像这样
class Geometry {
public:
enum {BOX, MESH} type;
std::string name;
};
class Mesh : public Geometry {
public:
std::string filename;
};
std::shared_ptr<Geometry> getGeometry() {
std::shared_ptr<Geometry> geom = std::make_shared<Geometry>();
geom->name = "geometry";
Mesh *mesh = new Mesh();
mesh->name = "name";
mesh->filename = "filename";
mesh->type = Geometry::MESH;
geom.reset(mesh);
return geom;
}
我需要扩展这些类提供的功能,所以我派生了这两个类
#include <memory>
#include <iostream>
class Geometry {
public:
enum {BOX, MESH} type;
std::string name;
};
class Mesh : public Geometry {
public:
std::string filename;
};
std::shared_ptr<Geometry> getGeometry() {
std::shared_ptr<Geometry> geom = std::make_shared<Geometry>();
geom->name = "geometry";
Mesh *mesh = new Mesh();
mesh->name = "name";
mesh->filename = "filename";
mesh->type = Geometry::MESH;
geom.reset(mesh);
return geom;
}
class GeometryDerived : public Geometry {
public:
void consumeGeometry() {
Geometry geom = static_cast<Geometry>(*this);
std::cout << geom.name << std::endl;
if(geom.type == Geometry::MESH) {
Mesh *mesh = static_cast<Mesh*>(&geom);
std::cout << mesh->filename << std::endl;
// mesh->get_output();
}
}
};
class MeshDerived : public Mesh {
public:
std::string get_output() {
return this->filename;
}
};
int main(int argc, char** argv)
{
std::shared_ptr<Geometry> geom = getGeometry(); // this object is returned by the library
std::shared_ptr<GeometryDerived> geomDerived = std::static_pointer_cast<GeometryDerived>(geom);
geomDerived->consumeGeometry();
return 0;
}
我得到一个segfault 行(在我的实际代码中,它的垃圾字符串)
std::cout << mesh->filename << std::endl;
虽然其他ints 和doubles 打印正确。即使geom.name 也能正确打印。这里的字符串是怎么回事?在这里投射物体的正确方法是什么?两次投射物体看起来很难看。下面是GDB 的输出
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./cpp-example...
(gdb) run
Starting program: /home/user/cpp-example
name
Program received signal SIGSEGV, Segmentation fault.
__memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:383
383 ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S: No such file or directory.
(gdb) bt
#0 __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:383
#1 0x00007ffff7c247b2 in _IO_new_file_xsputn (n=140737488346512, data=0xdb8bbc853a3b3400, f=<optimized out>) at fileops.c:1236
#2 _IO_new_file_xsputn (f=0x7ffff7d7e6a0 <_IO_2_1_stdout_>, data=0xdb8bbc853a3b3400, n=140737488346512) at fileops.c:1197
#3 0x00007ffff7c18541 in __GI__IO_fwrite (buf=0xdb8bbc853a3b3400, size=1, count=140737488346512, fp=0x7ffff7d7e6a0 <_IO_2_1_stdout_>) at libioP.h:948
#4 0x00007ffff7ed2824 in std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) ()
from /lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x0000555555556858 in GeometryDerived::consumeGeometry (this=0x55555556def0) at ../downcasting.cpp:23
#6 0x0000555555556513 in main (argc=1, argv=0x7fffffffdec8) at ../downcasting.cpp:53
编辑 1: 以下更改工作正常,但这不是我想要的
int main(int argc, char** argv)
{
std::shared_ptr<Geometry> geom = getGeometry();
if(geom->type == Geometry::MESH) {
std::shared_ptr<MeshDerived> meshDerived = std::static_pointer_cast<MeshDerived>(geom);
std::cout << meshDerived->filename << std::endl;
}
// std::shared_ptr<GeometryDerived> geomDerived = std::static_pointer_cast<GeometryDerived>(geom);
// geomDerived->consumeGeometry();
return 0;
}
【问题讨论】:
-
您认为
Geometry geom = static_cast<Geometry>(*this);行做了什么? (如果您不尝试制作副本,为什么还要费心铸造呢?)
标签: c++ inheritance casting shared-ptr