多态性转换不适用于我的 类
Polymorphism cast doesn't work for my classes
抱歉问了我相信一个重复的问题,但我无法弄清楚这里的问题,也许我对此的理解不正确。
设置
class Job {
public:
virtual bool createJob() {
return false;
}
};
class Limit {
public:
virtual bool updateLimit() {
return false;
}
};
class Base : public Job, public Limit {
private:
std::string cx;
public:
virtual ~Base() {
}
};
class DerivedJob : public Base {
protected:
std::string ax;
std::string bx;
std::vector<std::string> vx;
public:
bool createJob() override {
return true;
}
};
class DerivedLimit : public Base {
protected:
std::string ax;
std::string bx;
std::vector<std::string> vx;
public:
bool updateLimit() override {
return true;
}
};
应该可以吗?
Base parent;
auto stat = static_cast<DerivedJob&>(base);
std::cout << "JOB: " << std::to_string(stat.createJob());
std::cout << "LIMIT: " << std::to_string(stat.updateLimit());
auto dyn = dynamic_cast<DerivedJob&>(base);
std::cout << "JOB: " << std::to_string(dyn.createJob());
std::cout << "LIMIT: " << std::to_string(dyn.updateLimit());
auto stat1 = static_cast<DerivedLimit&>(base);
std::cout << "JOB: " << std::to_string(stat1.createJob());
std::cout << "LIMIT: " << std::to_string(stat1.updateLimit());
auto dyn1 = dynamic_cast<DerivedLimit&>(base);
std::cout << "JOB: " << std::to_string(dyn1.createJob());
std::cout << "LIMIT: " << std::to_string(dyn1.updateLimit());
我尝试了很多示例并阅读了很多帖子,但是当我将 string
和其他垃圾添加到派生 类 时,它停止工作,也许我对此的基本理解不正确?
别太苛刻,我只是c++小白:D
感谢您花时间向我解释这些事情。
附加问题
动态投射是如何工作的?
例子
class Device {
private:
Base _base;
public:
Device(int x) {
if (x == 5) {
DerivedJob object;
object.test = 5;
object.test2 = 1;
_base = object;
} else if (x == 7) {
DerivedLimit object;
object.test = 5;
object.test2 = 1;
_base = object;
} ...
}
}
正如 dxiv 在他的评论中已经指出的那样,static/dynamic_cast 只有在所讨论的对象实际上是 class.
时才有效
它们是对编译器的提示,即 pointer/reference 到某个变量是某个 class,但它们不会将基 class 转换为子 class.
所以这行得通:
Base *basePtr = new DerivedJob();
std::cout << "JOB: " << std::to_string(basePtr->createJob()); //True, because DerivedJob overrides the virtual method.
std::cout << "LIMIT: " << std::to_string(basePtr->updateLimit()); //False, because DerivedJob inherits the method from its parent.
static_cast<DerivedJob *>(basePtr)->doSomethingSpecificForDerivedJob();
auto dyn1 = dynamic_cast<DerivedLimit *>(basePtr); //NULL, because basePtr is NOT a DerivedLimit.
auto dyn2 = dynamic_cast<Limit *>(basePtr); //Address to basePtr, because basePtr inherits from Limit.
因此,总而言之,使用 static_cast 调用派生 class 现有的方法 specific/only,并且仅当您完全确定它是 class 或继承 class.
如果您不是 100% 确定并且想事先检查,请使用 dynamic_cast。
要了解评论,您(可能)想要的是这样的:
Base *base = nullptr;
if (smth == 1)
{
DerivedJob *job = new DerivedJob(); //Dynamic allocation instead of static!
job->test1 = 1; //Requires 'test1' to be public
base = job; //Passes the pointer to the variable pointing to the base class.
}
delete base; Cleans up the instantiated DerivedJob instance.
抱歉问了我相信一个重复的问题,但我无法弄清楚这里的问题,也许我对此的理解不正确。
设置
class Job {
public:
virtual bool createJob() {
return false;
}
};
class Limit {
public:
virtual bool updateLimit() {
return false;
}
};
class Base : public Job, public Limit {
private:
std::string cx;
public:
virtual ~Base() {
}
};
class DerivedJob : public Base {
protected:
std::string ax;
std::string bx;
std::vector<std::string> vx;
public:
bool createJob() override {
return true;
}
};
class DerivedLimit : public Base {
protected:
std::string ax;
std::string bx;
std::vector<std::string> vx;
public:
bool updateLimit() override {
return true;
}
};
应该可以吗?
Base parent;
auto stat = static_cast<DerivedJob&>(base);
std::cout << "JOB: " << std::to_string(stat.createJob());
std::cout << "LIMIT: " << std::to_string(stat.updateLimit());
auto dyn = dynamic_cast<DerivedJob&>(base);
std::cout << "JOB: " << std::to_string(dyn.createJob());
std::cout << "LIMIT: " << std::to_string(dyn.updateLimit());
auto stat1 = static_cast<DerivedLimit&>(base);
std::cout << "JOB: " << std::to_string(stat1.createJob());
std::cout << "LIMIT: " << std::to_string(stat1.updateLimit());
auto dyn1 = dynamic_cast<DerivedLimit&>(base);
std::cout << "JOB: " << std::to_string(dyn1.createJob());
std::cout << "LIMIT: " << std::to_string(dyn1.updateLimit());
我尝试了很多示例并阅读了很多帖子,但是当我将 string
和其他垃圾添加到派生 类 时,它停止工作,也许我对此的基本理解不正确?
别太苛刻,我只是c++小白:D
感谢您花时间向我解释这些事情。
附加问题
动态投射是如何工作的?
例子
class Device {
private:
Base _base;
public:
Device(int x) {
if (x == 5) {
DerivedJob object;
object.test = 5;
object.test2 = 1;
_base = object;
} else if (x == 7) {
DerivedLimit object;
object.test = 5;
object.test2 = 1;
_base = object;
} ...
}
}
正如 dxiv 在他的评论中已经指出的那样,static/dynamic_cast 只有在所讨论的对象实际上是 class.
时才有效它们是对编译器的提示,即 pointer/reference 到某个变量是某个 class,但它们不会将基 class 转换为子 class.
所以这行得通:
Base *basePtr = new DerivedJob();
std::cout << "JOB: " << std::to_string(basePtr->createJob()); //True, because DerivedJob overrides the virtual method.
std::cout << "LIMIT: " << std::to_string(basePtr->updateLimit()); //False, because DerivedJob inherits the method from its parent.
static_cast<DerivedJob *>(basePtr)->doSomethingSpecificForDerivedJob();
auto dyn1 = dynamic_cast<DerivedLimit *>(basePtr); //NULL, because basePtr is NOT a DerivedLimit.
auto dyn2 = dynamic_cast<Limit *>(basePtr); //Address to basePtr, because basePtr inherits from Limit.
因此,总而言之,使用 static_cast 调用派生 class 现有的方法 specific/only,并且仅当您完全确定它是 class 或继承 class.
如果您不是 100% 确定并且想事先检查,请使用 dynamic_cast。
要了解评论,您(可能)想要的是这样的:
Base *base = nullptr;
if (smth == 1)
{
DerivedJob *job = new DerivedJob(); //Dynamic allocation instead of static!
job->test1 = 1; //Requires 'test1' to be public
base = job; //Passes the pointer to the variable pointing to the base class.
}
delete base; Cleans up the instantiated DerivedJob instance.