我创建了这个.h文件
#pragma once
namespace Core
{
class IComparableObject
{
public:
virtual int CompareTo(IComparableObject obj)=0;
};
}
Run Code Online (Sandbox Code Playgroud)
但是如果方法是虚拟的,编译器不喜欢IComparableObject obj param
virtual int CompareTo(IComparableObject obj) {}
Run Code Online (Sandbox Code Playgroud)
没关系,但是我希望它是虚拟的.我怎么能设法做到这一点?可能吗?
可能重复:
学习C++:多态和切片
这是我之前提出的一个问题.这些类看起来像这样:
class Enemy
{
public:
void sayHere()
{
cout<<"Here"<<endl;
}
virtual void attack()
{
}
};
class Monster: public Enemy
{
public:
void attack()
{
cout<<"RAWR"<<endl;
}
};
class Ninja: public Enemy
{
public:
void attack()
{
cout<<"Hiya!"<<endl;
}
};
Run Code Online (Sandbox Code Playgroud)
我是C++的新手,我很困惑为什么这只能用指针(忍者和怪物都来自敌人):
int main()
{
Ninja ninja;
Monster monster;
Enemy *enemies[2];
enemies[0] = &monster;
enemies[1] = &ninja;
for (int i = 0; i < 2; i++)
{
enemies[i]->attack();
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么我不能这样做呢?:
int main()
{
Ninja ninja;
Monster …Run Code Online (Sandbox Code Playgroud) 当我们将派生类的对象分配或复制到其基类的对象时,会发生对象切片,从而在该过程中丢失它的派生部分.
这里有更深入的解释:C++中的切片问题是什么?.
(我自己,我不认为它是一个问题,而是语言价值语义的自然结果,但这不是这个问题的重点.)
我想知道的是:有没有你有意使用它的情况?这是一个"工作的正确工具"吗?
假设我有一个抽象类Cat,它有一些具体的子类Wildcat,Housecat等.
我希望我的数组能够存储指向一种猫的指针,而不知道它究竟是哪种类型.
当我尝试动态分配Cat数组时,它似乎不起作用.
Cat* catArray = new Cat[200];
Run Code Online (Sandbox Code Playgroud) (事先原谅noob问题)
我有4个班:
class Person {};
class Student : public Person {};
class Employee : public Person {};
class StudentEmployee : public Student, public Employee {};
Run Code Online (Sandbox Code Playgroud)
基本上Person是基类,其直接由两个子类Student和Employee.StudentEmployee使用多重继承来子类化Student和Employee.
Person pat = Person("Pat");
Student sam = Student("Sam");
Employee em = Employee("Emily");
StudentEmployee sen = StudentEmployee("Sienna");
Person ppl[3] = {pat, sam, em};
//compile time error: ambiguous base class
//Person ppl[4] = {pat, sam, em, sen};
Run Code Online (Sandbox Code Playgroud)
当我使用Person基类的数组时,我可以将Person它的所有子类放在这个数组中.除了StudentEmployee,给出基础模糊的原因. …
我有一组多态对象,都来自我的Animal类:Cat,Dog和MonkeyFish.
我通常的操作模式是将这些对象存储在Animal指针的向量中,如下所示:
std :: vector <Animal*> my_vector;
my_vector.push_back( new Animal_Cat() ); my_vector.push_back( new Animal_Dog() ); my_vector.push_back( new Animal_MonkeyFish() );
生活很美好......或者是它?
我最近被告知我应该尽量避免以这种方式分配内存,因为它使内存管理成为一件苦差事.当我需要销毁my_vector时,我必须遍历所有元素并删除所有内容.
我不认为我可以存储引用的向量(我可能错了),所以看起来存储Animal对象的向量是我唯一的选择.
我什么时候应该选择使用指针向量与对象向量?一般来说,哪种方法更可取?(我想尽可能减少对象复制.)
我正在编写一组扩展的自定义异常std::exception.在某些代码中,当捕获异常时,我只是重新throw启动链,直到驱动程序main函数调用catches并打印结果.但是,最终打印的所有内容都是"std :: exception".这似乎不是我之前处理的范围问题.
为什么我的异常消息不能打印?
我的异常代码:
// General exception class
struct MyException : public std::exception
{
std::string _msg;
MyException(const std::string &exception_name) : _msg(exception_name) {}
void setMessage(const std::string &message)
{
_msg += ": " + message + "\n";
}
void setLocation(const char * func, const char * file, const int line)
{
_msg += " In function " + std::string(func) + "(" + file + ":" + std::to_string(line) + ")";
}
const …Run Code Online (Sandbox Code Playgroud) 我没有和我一起使用有效的C++,这让我非常烦恼,所以我必须要求自己的理智.特定
class Foo : public Bar{}
void MyFunc(Bar &_input);
Run Code Online (Sandbox Code Playgroud)
如果我通过了Foo,我是否与切片问题纠缠在一起还是我避免了它?
请看下面设计类聚合的两个简化示例.
解决方案1
头
// need include, forward declaration is not enough
#include "door.h"
class CGarage
{
public:
CGarage(const std::string &val);
private:
CDoor m_door;
};
Run Code Online (Sandbox Code Playgroud)
资源
#include "garage.h"
CGarage::CGarage(const std::string &val)
:m_door(val)
{
}
Run Code Online (Sandbox Code Playgroud)
解决方案2
头
#include "smart_ptr.hpp"
// forward declaration
class CDoor;
class CGarage
{
public:
CGarage(const std::string &val);
private:
scoped_ptr<CDoor> m_door;
};
Run Code Online (Sandbox Code Playgroud)
资源
#include "garage.h"
#include "door.h"
CGarage::CGarage(const std::string &val)
:m_door(new CDoor(val))
{
}
Run Code Online (Sandbox Code Playgroud)
有关创建CDoor成员的问题
您在示例设计中看到了哪些优点/缺点(CDoor与自动分配的动态分配)?
这就是我想出的:
解决方案1:
+没有内存处理或生命周期的问题
+在运行时不需要昂贵的内存分配
- 在头文件中需要额外的包含(编译速度更慢?,更接近CDoor) - >头文件中的许多包含被认为是坏的...
解决方案2:
+标头中的CDoor松散耦合(仅需要前向声明)
- 内存需要由程序员处理
您通常喜欢哪种设计?
class Material
{
public:
void foo()
{
cout << "Class Material";
}
};
class Unusual_Material : public Material
{
public:
void foo()
{
cout << "Class Unusual_Material";
}
};
int main()
{
Material strange = Unusual_Material();
strange.foo(); //outputs "Class Material"
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我希望这导致"Class Unusual_Material"显示在控制台上.有没有办法实现这个目标?在我的程序中,我有一个类材料,从中可以得到其他更具体的材料.方法Material :: foo()表示Material中适用于大多数材料的方法,但是在某种程度上,需要为具有不寻常属性的材料定义另一个foo().
程序中的所有对象都包含一个Material字段.如果他们被分配了一个不寻常的材料,我希望调用派生的,不寻常的foo.
这可能要么很简单,要么不可能,但无论如何我无法弄明白.
谢谢
c++ ×10
arrays ×2
polymorphism ×2
abstract ×1
base-class ×1
class-design ×1
exception ×1
hierarchy ×1
inheritance ×1
pointers ×1
throw ×1