- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 C++ 作业,我们必须在其中实现一些继承自 ABC 的类,称为 Object。每个对象都有一个特定的 ID。
我们有一个 String 类(使用 std::string 实现),它是一个对象,将被用来代替 std::string。
我们还有一个 PlaneComponent ABC,它是一个对象并且有一个数据成员“String description”。另一个类是 PassengerCompartment,它是一个 PlaneComponent 并且有一个数据成员,该数据成员是指向另一个 PassengerCompartment(如内部 PassengerCompartment)的指针。
我们有一个函数“克隆”,它返回一个对象*给克隆的对象。
我在 main 中创建了一个名为“test”的 PassengerCompartment 对象和一个 Object* ptr 并克隆了“test”对象。
然后我检查了这些 Objects(PassengerCompartments) 是否相等并得到“不相等”,这是不正确的。所以我开始检查相等的功能。问题是当我调用 String::equal 并且在它的主体中我有这个命令:
cout << ((String*)other_object)->get_string() << endl;
(get_string() 是对返回 std::string 的 Class String 的 std::string 的访问器)
我遇到段错误:
Program received signal SIGSEGV, Segmentation fault.
0xb76e2d88 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string () from /usr/lib/libstdc++.so.6
这是 gdb 中 bt full 的输出:
(gdb) bt full
#0 0xb767ed88 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string () from /usr/lib/libstdc++.so.6
No symbol table info available.
#1 0x0804bb10 in String::get_string (this=0xbfdb5560) at objects.h:55
No locals.
#2 0x0804b2de in String::equal (this=0xbfdb5568, other_object=0xbfdb5560) at objects.cpp:129
No locals.
#3 0x0804b5a5 in PlaneComponent::equal (this=0xbfdb5560, other_object=0xbfdb5560) at objects.cpp:191
No locals.
#4 0x0804ba3a in PassengerCompartment::equal (this=0xbfdb5560, other_object=0xbfdb5560) at objects.cpp:372
result = false
#5 0x080492b4 in main () at main.cpp:47
anew = {<Object> = {_vptr.Object = 0x804c008, id = 1}, the_string = {static npos = 4294967295,
_M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x804f014 "A Class"}}}
test = {<PlaneComponent> = {<Object> = {_vptr.Object = 0x804bfc8, id = 2}, description = {<Object> = {_vptr.Object = 0x804c008, id = 1},
the_string = {static npos = 4294967295,
_M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>},
_M_p = 0x804f014 "A Class"}}}}, inner_PassengerCompartment = 0x0}
ptr = (class Object *) 0x804f020
这是 valgrind 的输出:
==14233== Bad permissions for mapped region at address 0x804C004
==14233== at 0x40CFD88: std::string::string(std::string const&) (in /usr/lib/libstdc++.so.6.0.9)
==14233== by 0x804BB0F: String::get_string() (objects.h:55)
==14233== by 0x804B2DD: String::equal(Object const*) (objects.cpp:129)
==14233== by 0x804B5A4: PlaneComponent::equal(Object const*) (objects.cpp:191)
==14233== by 0x804BA39: PassengerCompartment::equal(Object const*) (objects.cpp:372)
==14233== by 0x80492B3: main (main.cpp:47)
在 String::equal(Object* other_object) 中,在 gdb 中我得到这个:
(gdb) print *this
$1 = {<Object> = {_vptr.Object = 0x804bfa8, id = 1}, the_string = {static npos = 4294967295,
_M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x804f014 "A Class"}}}
(gdb) print *other_object
$2 = {_vptr.Object = 0x804bf68, id = 2}
所以在我看来,Object* ptr 只是一个对象,也不是 PassengerCompartment。
所以问题出在克隆函数上? (在这个函数“Object* PassengerCompartment::clone(void)”中我有这个:
return new PassengerCompartment(*this);
我做错了什么?我真的想不通。也许复制构造函数?请告诉我您希望我包含哪些其他信息!
预先感谢您的帮助!
一些额外的注意事项:
Object* Object::clone() 是纯虚拟的。
This is the code of the equal functions and the copy constructors
<强> These are the source files as asked ||| Mirror here
最佳答案
在检查了完整的源代码之后,它有很多问题。但是有 3 条主线实际上是错误的,其余的归结为 const 正确性。
一个。在 PassengerCompartment::equal 中,您没有返回任何东西。您需要返回结果;不返回 void 的函数中缺少返回值将调用未定义的行为。
B.
cout << dynamic_cast<const String&>(*other_object).get_string() << endl;
您正在尝试将 PlaneComponent 引用转换为 String 引用。 PlaneComponent 不会在其层次结构中的任何位置继承 String。我怀疑你的意思是:
cout << other_object->toString().get_string() << endl;
C.
if ( the_string == ((String*)other_object)->the_string)
与 B 相同的问题。PlaneComponent 未实现 String 接口(interface),因此无法转换为它。这是非法转换,会调用未定义的行为。
您的其余问题归结为常量正确性。当涉及到函数参数时,您对 const-correctness 很在行。例如,equal 方法不会修改我们正在比较的对象,因此您将其视为只读指针:很好。但是,在将方法定义为只读时,您根本没有这样做。例如:
virtual bool equal(const Object* other_object);
应该是:
virtual bool equal(const Object* other_object) const;
如果不始终如一地执行此操作,上述更正将引发编译器错误。这是更正后的完整来源:
///////////////////////////////////////////////////////////////////////////////
// objects.h
#include <iostream>
#include <string>
class String;
class Object
{
private:
int id;
public:
//constructors and destructor
Object(void);
Object(const Object& object_);
virtual ~Object(void);
//general functionality
virtual bool equal(const Object* other_object) const { return (id == other_object->id); }
bool identical(const Object& other_object) const { return (this == &other_object); }
virtual String toString(void) const = 0;
virtual Object* clone(void) const = 0;
//accessor
int get_id(void) const {return id;}
};
///////////////////////////////////////////////////////////////////////////////
// objects.cpp
class String : public Object
{
private:
std::string the_string;
public:
//constructors, assignment operator and destructor
String(void);
String(std::string given);
String(const String& given);
String& operator=(const String& given);
virtual ~String(void);
//String(const std::string& given)
//general functionality
int length(void);
void clear(void);
char& at(int pos);
void updateAT(int pos, std::string given);
void concat(const String& given);
void print(void);
virtual String toString(void) const;
virtual Object* clone(void) const;
virtual bool equal(const Object* other_object) const;
//accessor
std::string get_string(void) const { std::cout << the_string << std::endl; return the_string; }
};
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
class PlaneComponent : public Object
{
private:
String description;
public:
//constructor and destructor
PlaneComponent(const String& describe_it);
PlaneComponent(const PlaneComponent& given);
virtual ~PlaneComponent(void);
//general functionality
virtual void ready_check(void) = 0;
//virtual void process(void) = 0;
virtual String toString(void) const = 0;
virtual bool equal(const Object* other_object) const = 0;
virtual Object* clone(void) const = 0;
//accessor
String get_description(void) const { return description; }
};
///////////////////////////////////////////////////////////////////////////////
class PassengerCompartment : public PlaneComponent
{
private:
PassengerCompartment* inner_PassengerCompartment;
public:
//constructor and destructor
PassengerCompartment(const String& description_given);
PassengerCompartment(const PassengerCompartment& given);
//constructors for the inner passenger_compartment
PassengerCompartment(const String& description_given, bool for_innerPC);
PassengerCompartment(const PassengerCompartment& given, bool for_innerPC);
virtual ~PassengerCompartment(void);
//general functionality
//void more_space(const String& inner_description);
virtual String toString(void) const;
virtual void ready_check(void);
virtual Object* clone(void) const;
virtual bool equal(const Object* other_object) const;
//accessor
PassengerCompartment* get_inner_PassengerCompartment(void);
};
///////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <sstream>
#include <cstdlib>
using namespace std;
///////////////////////////////////////////////////////////////////////////////
Object::Object(void)
{
cout << "Object just created!" << endl;
static int id_ = 1;
id = id_;
id_++;
}
Object::Object(const Object& object_)
{
id = object_.id;
cout << "Copy of Object just created!" << endl;
}
Object::~Object(void)
{
id = -1;
cout << "Object to be destroyed!" << endl;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
String::String(void)
{
cout << "String just created!" << endl;
}
String::String(std::string given)
{
the_string = given;
cout << "String just created!" << endl;
}
String::String(const String& given) : Object(given)
{
the_string = given.the_string;
cout << "Copy of String just created!" << endl;
}
String::~String(void)
{
the_string.empty();
cout << "String to be destroyed!" << endl;
}
String& String::operator=(const String& given)
{
if (&given != this)
{
this->the_string = given.the_string;
}
return *this;
}
////////////////////////////////////////////
int String::length(void)
{
return the_string.length();
}
void String::clear(void)
{
the_string.clear();
}
char& String::at(int pos)
{
return the_string.at(pos);
}
void String::updateAT(int pos, string given)
{
the_string.replace(pos, 1, given);
}
void String::concat(const String& given)
{
the_string.append(given.the_string);
}
void String::print(void)
{
for (int i = 0; i < the_string.length(); i++)
{
cout << the_string.at(i);
}
cout << endl;
}
////////////////////////////////////////////
String String::toString(void) const
{
ostringstream resultstream;
resultstream << "String with content: <<" << the_string
<< ">> and id: " << Object::get_id();
String result( resultstream.str() );
return result;
}
Object* String::clone(void) const
{
return new String(*this);
}
bool String::equal(const Object* other_object) const
{
cout <<"the_string: " << endl;
//this->print();
cout << this->get_string() << endl;
cout <<"other_object the_string: " << endl;
cout << other_object->toString().get_string() << endl;
//cout << dynamic_cast<String*>(other_object)->get_string() << endl;
//cout << ((String*)other_object)->get_string() << endl;
//cout << ((String*)other_object)->the_string << endl;
//((PassengerCompartment*)other_object)->get_description().print();
//check if strings are the same
if ( the_string == other_object->toString().get_string())
{
//check id
if ( Object::equal(other_object) )
return true;
else
return false;
}
else
return false;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
PlaneComponent::PlaneComponent(const String& describe_it) : description(describe_it)
{
cout << description.get_string() << endl;
cout << "PlaneComponent just created!" << endl;
}
PlaneComponent::PlaneComponent(const PlaneComponent& given) : Object(given), description(given.description)
{
cout << description.get_string() << endl;
cout << "PlaneComponent just created!" << endl;
}
PlaneComponent::~PlaneComponent(void)
{
cout << "PlaneComponent to be destroyed!" << endl;
}
/*PlaneComponent::PlaneComponent(const String& describe_it)
{
description = describe_it;
cout << "PlaneComponent just created!" << endl;
}*/
////////////////////////////////////////////
bool PlaneComponent::equal(const Object* other_object) const
{
cout << "------------------" << endl;
cout << "------------------" << endl;
cout << "------------------" << endl;
cout << "------------------" << endl;
cout << "--------PlaneComponent::equal----------" << endl;
this->get_description().print();
dynamic_cast<const PlaneComponent*>(other_object)->get_description().print();
cout << "--------PlaneComponent::equal----------" << endl;
cout << "------------------" << endl;
cout << "------------------" << endl;
cout << "------------------" << endl;
cout << "------------------" << endl;
//check if description is the same
//if ( description.equal(((PassengerCompartment*)other_object)->get_description) )
if ( description.equal(other_object) )
{
//check id
if ( Object::equal(other_object) )
return true;
else
return false;
}
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
PassengerCompartment::PassengerCompartment(const String& description_given) : PlaneComponent(description_given)
{
inner_PassengerCompartment = NULL;
cout << "PassengerCompartment just created!" << endl;
//float random = ((float)rand())/(float)(RAND_MAX);
//if ( random >= 0.5 )
//{
// String inner_result("Inner: ");
// inner_result.concat(description_given);
// inner_PassengerCompartment = new PassengerCompartment(inner_result, true);
//}
}
PassengerCompartment::PassengerCompartment(const PassengerCompartment& given) : PlaneComponent(given)
{
if (given.inner_PassengerCompartment != NULL )
{//if the given PassengerCompartment has an inner PassengerCompartment, copy that, too
inner_PassengerCompartment = new PassengerCompartment(*(given.inner_PassengerCompartment), true);
std::cout << "Inner PassengerCompartment just created!" << std::endl;
}
else
inner_PassengerCompartment = NULL;
std::cout << "PassengerCompartment just created!" << std::endl;
}
PassengerCompartment::PassengerCompartment(const String& description_given, bool for_innerPC) : PlaneComponent(description_given)
{
static bool already_allocated_inner_space = false;
if ( !already_allocated_inner_space )
{
inner_PassengerCompartment = NULL;
already_allocated_inner_space = true;
}
}
PassengerCompartment::PassengerCompartment(const PassengerCompartment& given, bool for_innerPC) : PlaneComponent(given)
{
inner_PassengerCompartment = NULL;
}
PassengerCompartment::~PassengerCompartment(void)
{
static bool did_it = false;
if ( !did_it )
{
if ( inner_PassengerCompartment != NULL )
{
did_it = true;
delete inner_PassengerCompartment;
inner_PassengerCompartment = NULL;
cout << "Inner Passenger Compartment to be destroyed!" << endl;
}
cout << "Passenger Compartment to be destroyed!" << endl;
did_it = false;
}
}
////////////////////////////////////////////
/*void PassengerCompartment::more_space(const String& inner_description)
{
static bool have_added_space = false;
if (!have_added_space)
{
float random = ((float)rand())/(float)(RAND_MAX);
if ( random >= 0.5 )
{
inner_PassengerCompartment = new PassengerCompartment(inner_description);
}
have_added_space = true;
}
}*///////writen a copy constructor instead!!
String PassengerCompartment::toString(void) const
{
ostringstream resultstream;
resultstream << "This is a Passenger Compartment with description: \"";
resultstream << get_description().get_string();
resultstream << "\" and id: " << Object::get_id();
resultstream << endl;
if ( inner_PassengerCompartment == NULL)
resultstream << "With no inner Passenger Compartment";
else
{
resultstream << "With an inner Passenger Compartment with description: \"";
resultstream << inner_PassengerCompartment->get_description().get_string();
resultstream << "\" and id:" << ((Object*)inner_PassengerCompartment)->get_id();
}
String result( resultstream.str() );
return result;
}
void PassengerCompartment::ready_check(void)
{
cout << "Description of Passenger Compartment:" << endl;
get_description().print();
cout << "Passenger Compartment OK!" << endl;
if ( inner_PassengerCompartment != NULL )
{
cout << "Description of Inner Passenger Compartment:" << endl;
inner_PassengerCompartment->get_description().print();
cout << "Inner Passenger Compartment OK!" << endl;
}
}
Object* PassengerCompartment::clone(void) const
{
cout << "_______________PassengerCompartment::Clone_______________" << endl;
return new PassengerCompartment(*this);
}
////////////////////////////////////////////
PassengerCompartment* PassengerCompartment::get_inner_PassengerCompartment(void)
{
return inner_PassengerCompartment;
}
bool PassengerCompartment::equal(const Object* other_object) const
{
bool result = false;
//if there is an inner compartment check if equal
if ( inner_PassengerCompartment != NULL )
{ /*//manually check for it's description and ID to avoid recursion
if ( get_description() == ((PlaneComponent*)other_object)->get_description() )
{ //check IDs
if ( get_id() == other_object->get_id() )
result = true;
else result = false;
}
else result = false;*/
if ( inner_PassengerCompartment->PlaneComponent::equal( ((PassengerCompartment*)other_object)->inner_PassengerCompartment ) )
result = true;
else result = false;
}
this->get_description().print();
dynamic_cast<const PassengerCompartment*>(other_object)->get_description().print();
cout << "------------------" << endl;
cout << "------------------" << endl;
//check for the passenger compartment itself
if ( PlaneComponent::equal(other_object) )
result = true;
else
result = false;
return result;
}
///////////////////////////////////////////////////////////////////////////////
// main.cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main(void)
{
//seed rand
srand( (unsigned int) (time(NULL)) );
String anew("A Class");
PassengerCompartment test(anew);
Object* ptr = test.clone();
cout << "THIS ID: " << test.get_id() << endl;
cout << "OTHER OBJECT ID:" << ptr->get_id() << endl;
if (test.equal(&test))
{
cout << "Equal" << endl;
}
else cout << "Not Equal" << endl;
cout << "-------------------Exiting main!----------------" << endl;
return 0;
}
最后,一定要清理你分配的资源。克隆的对象应该在某个时候被删除,但如果你使用类似 shared_ptr 的东西(来自 Boost 或 C++11)会更好。
最后一点:根据您散布在整个代码中的输出量来判断,我猜您还不知道如何使用调试器。我强烈推荐你学习这个。如果您可以学习如何使用调试器单步执行代码并查看执行之间的各种状态,那么您的许多挫败感都会消失,您不必觉得自己是在黑暗中编码。
关于关于 ABC、继承和虚函数的 C++ 赋值,试图找出段错误等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9154333/
我在 JavaScript 中使用正则表达式负前瞻来使用正则表达式匹配替换字符串中最后一次出现的字符串。 这是我的代码片段: var str = 'abc abc abc' var regex1 =
许多报告和开发团队必须使用该条件 where ABC>='00' and ABC='00' and ABC='0' and ABC ='00' 且 ABC ='0' 且 ABC< ='Z',我们在St
这个问题已经有答案了: What is the Java string pool and how is "s" different from new String("s")? [duplicate]
我有一个很长的正则表达式 (JavaScript),它包含以下构造: ((\\\\)|(\\[abc])|([^abc]))* 正则表达式表示: 匹配任何不包含字母 a、b 和 c 的字符串。 除非它
In [29]: re.findall("([abc])+","abc") Out[29]: ['c'] In [30]: re.findall("[abc]+","abc") Out[30]: ['
这个问题在这里已经有了答案: What is the difference between "text" and new String("text")? (13 个答案) 关闭 8 年前。 Stri
我正在尝试创建一个简单的抽象基类 Abstract它和它自己的方法一起提供了另外两个抽象基类的方法:Publisher和 Subscriber .当我尝试初始化具体类时 Concrete , 建立在
我正在学习如何使用egrep命令,我想找到一些在一行中重复3个字符的单词(例如,abc-abc-abc; ssd-ssd-ssd)。 我尝试了一些命令,例如 egrep '[a-z][a-z][a-z
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 6 年前。 Improve th
太晚了,我还不太明白。 我的文字看起来像这样: This is a [;;Text] and I want to match [center]everything without ;;[/cente
我有 junit 测试用例,我按以下方式使用了 Spy ,并且 Junit 在以下情况下失败。 @Spy private Abc abc; 但是运行成功。 @Spy Abc abc = new A
"abc def" "abcd efgh" 如果我有一个大字符串,其中有一个空格分隔两个不同长度的子字符串,那么从较大字符串中提取每个子字符串的最佳方法是什么? 因为这是一个字符串而不是数组,数组语法
我想知道 MySQLBDDColumns.Text 中是否存在值“Type de prise” 我得到了我想知道的值是否包含在 Texte_Caractéristiques.Text 但只有我有值“T
这个问题已经有答案了: What is the purpose of the var keyword and when should I use it (or omit it)? (19 个回答) 已
我试图找到一个正则表达式来匹配具有字符串“question”但不具有或不包含字符串“ion”的所有字符组合。 例子: questionxxxx ------>匹配 xxxquestion-------
我想使用正则表达式从文件中读取特定字符之间的多个字符串。我已经尝试了以下代码,但无法获得预期的结果。 我的输入文件包含以下格式的数据: #*OQL[C++]: Extending C++ with a
这个问题已经有答案了: Are double and single quotes interchangeable in JavaScript? (23 个回答) 已关闭 7 年前。 jQuery 中
我有一个工作函数: $('#hints').after( 'Hint 1' ) 我正在尝试编辑data-content="Hint 1 Content"使用 jQuery。 我的职能是: fun
这里有两个简单的类: class Abc { public int x; } class Bcd { public int y; } 鉴于 obj 是 object 类型,这里有几个测试 Abc 或
我在严格的 Java 环境中。 所以这个问题并不像标题中那么简单,我不是要解决我遇到的问题,它更理论化,以获得更好的知识。 我感兴趣的是用双引号或单引号匹配 src,但如果是双引号,它也必须用双引号结
我是一名优秀的程序员,十分优秀!