C++中矢量对象的铸造

C++中矢量对象的铸造,c++,vector,C++,Vector,我知道已经有人问过这个问题,但我至今找到的答案似乎都不够。我正在创建指向基类的指针向量,并向其中添加各种派生类。现在,基类有一个虚拟函数,该函数在所有派生类中都被重写,并且对每个派生类都是唯一的。因此,当我遍历向量并检索这些对象并调用该对象上的函数时,我需要它调用正确的函数,但它所做的只是调用基类版本。当我从向量中检索单个元素时,我甚至试图将它们转换回它们的原始类,但它们拒绝转换!e、 g vector<base*> myBase; DerivedClass *myDerived

我知道已经有人问过这个问题,但我至今找到的答案似乎都不够。我正在创建指向基类的指针向量,并向其中添加各种派生类。现在,基类有一个虚拟函数,该函数在所有派生类中都被重写,并且对每个派生类都是唯一的。因此,当我遍历向量并检索这些对象并调用该对象上的函数时,我需要它调用正确的函数,但它所做的只是调用基类版本。当我从向量中检索单个元素时,我甚至试图将它们转换回它们的原始类,但它们拒绝转换!e、 g

vector<base*> myBase;

DerivedClass *myDerived = static_cast<DerivedClass> myBase[i];
这是行不通的,尽管我读到的每一篇文章都表明应该这样做。我的调试器说,尽管如此,MyDevertive仍然是base类型,它的虚拟函数版本正在被调用

有什么想法吗

class BankAccount {
public:
BankAccount(string namein, string typein){
    name = namein;
    type = typein;
    balance = 0;
}
virtual string getType();
virtual void printTransactions() = 0;
virtual int withdraw(double amt){
    return getBalance() -amt;
}
};

class SavingsAccount: public BankAccount {
public:
SavingsAccount(string namein, string typein);
void addTransaction(string transType, string name);
virtual int withdraw(double amt);
void printTransactions();
virtual string getType();

private:

};

SavingsAccount::SavingsAccount(string namein, string typein): BankAccount(namein, typein) {

}

int SavingsAccount::withdraw(double amt){
double aBal = getBalance() - amt;
if (aBal > 0){
setBalance(aBal);
}
return getBalance() - amt;

}


class CheckingAccount: public SavingsAccount {
public:
CheckingAccount(string nameIn, string typein): SavingsAccount(nameIn, typein){

}
virtual int withdraw(double amt);
void printTransactions();
string getType(){
    return "Checking";
}

};

int CheckingAccount::withdraw(double amtIn){
double newBal = getBalance() - amtIn;
if (newBal < 500.00 && newBal > 2.49) {
    setBalance(newBal - 2.50);
}
return newBal;
}


支票账户是储蓄账户的子账户。对不起。

你试过这样的东西吗

class base
{
public:

inline DerivedClass *GetDerived() {return (DerivedClass*)this;}

...
};

DerivedClass *myDerived = myBase[i]->GetDerived();

你的概念是正确的,不需要任何铸造。虚拟函数的全部要点是,如果您持有基类指针或引用并调用虚拟函数,则将在运行时调用该函数的最派生版本

我看到的错误是:

    if (type.compare("Checking") == 0) {
        CheckingAccount myCheck1 = CheckingAccount(name, type);
        myAccts.push_back(&myCheck1);
您正在堆栈上创建一个检查帐户,然后获取它的地址并将该地址推送到向量中。在if块结束时,myCheck1将超出范围并被销毁。向量将具有指向堆栈中某个位置的地址,并且将具有未定义的行为

相反,你应该:

    if (type.compare("Checking") == 0) {
        myAccts.push_back(new CheckingAccount(name, type));
其他类型也类似。扔掉所有的石膏。在这个版本中,您必须删除向量末尾的所有项。如果您使用std::vector,则unique_ptr将负责清理分配的对象。

您需要使用new来创建帐户。。。你有:

if (...)
{
    CheckingAccount myCheck1 = CheckingAccount(name, type);
    myAccts.push_back(&myCheck1);
}
…myCheck1在离开该if作用域时会被销毁,留下一个指向堆栈上具有未定义行为(如果被访问)的有效随机位置的指针。改为:

if (type == "Checking")
    myAccts.push_back(new CheckingAccount(name, type));
然后需要对向量元素进行匹配删除。Google C++新的删除教程是个不错的主意。下一个阶段是学习如何使用智能指针,例如-std::shared_pointer,它消除了记住删除的负担

情况3可更正/简化为:

         for (int x = 0; x < myAccts.size(); x++)
            if (myAccts[x]->getName() == name && myAccts[x]->getType() == type) {
                double y = myAccts[x]->withdraw(amt); 
                if (y < 0)
                     cout << "Insufficient funds!";
                if (type == "Checking" && y < 497.5)
                        cout << "Withdrawal fee: $ 2.50" << endl;
            }

请特别注意双y=myAccts[x]->drawinAmt;-虚拟函数确保调用正确的版本,而无需在调用代码中执行任何特定于类型的操作。

DerivedClass*myDerived=static_cast myBase[i];使用动态\u cast-优于静态\u cast动态cast返回Null@user3712524-那么对象不是DerivedClass-请阅读dynamic_cast粘贴您的类的基础和派生…向下转换时,您应该使用dynamic_cast,因为它允许您检查您正在装箱的对象是否确实是派生类型。否则,演员阵容的结果就没有多大意义,可能会让人头疼。
         for (int x = 0; x < myAccts.size(); x++)
            if (myAccts[x]->getName() == name && myAccts[x]->getType() == type) {
                double y = myAccts[x]->withdraw(amt); 
                if (y < 0)
                     cout << "Insufficient funds!";
                if (type == "Checking" && y < 497.5)
                        cout << "Withdrawal fee: $ 2.50" << endl;
            }