我是C ++的新手,并编写了一个小程序来了解有关OOD和多态的更多信息。
总之,我有一个基类(WeeklyCompCalculator
),它包含一个成员变量(string description
),它通过派生类(FixedCompCalculator
)中的构造函数调用传入。 / p>
当我使用const string
(FIXED_SCHEME)初始化基类时,一切正常:
FixedCompCalculator::FixedCompCalculator() : WeeklyCompCalculator(FIXED_SCHEME) {}
但是,当我尝试使用字符串文字进行初始化时,描述成员已损坏:
FixedCompCalculator::FixedCompCalculator() : WeeklyCompCalculator("$600 Weekly") {}
我在下面列出了相关的代码。一个有趣的观察是,如果我修改shoe_comp.cpp
使用原始指针而不是shared_ptrs,问题就会消失。
comp_calculator.h
namespace ShoeCompUtil {
const string FIXED_SCHEME = "$600 Weekly";
class WeeklyCompCalculator {
public:
WeeklyCompCalculator(const string&);
virtual ~WeeklyCompCalculator();
virtual double calculate( const int shoePrice, const int weeklyHours, const int weeklyUnits ) const = 0;
string getDescription() const;
private:
const string& description;
};
class FixedCompCalculator : public WeeklyCompCalculator {
public:
FixedCompCalculator();
virtual double calculate( const int shoePrice, const int weeklyHours, const int weeklyUnits ) const;
};
};
comp_calculator.cpp
WeeklyCompCalculator::WeeklyCompCalculator(const string& descr): description{descr} {}
WeeklyCompCalculator::~WeeklyCompCalculator(){}
string WeeklyCompCalculator::getDescription() const {
const string descr{description};
return descr;
}
FixedCompCalculator::FixedCompCalculator() : WeeklyCompCalculator("$600 Weekly") {}
double FixedCompCalculator::calculate( const int shoePrice, const int weeklyHours, const int weeklyUnits ) const
{
return 600;
}
shoe_comp.cpp
cout << "Computing best compensation scheme given shoe_price = " << shoePrice << ", weeklyHours = " << weeklyHours << ", weeklyUnits = " << weeklyUnits << endl;
vector<shared_ptr<WeeklyCompCalculator>> calculators { make_shared<FixedCompCalculator>(), make_shared<HybridCompCalculator>(), make_shared<CommissionCompCalculator>() };
double maxComp = -1;
string maxDescr = "";
for( const shared_ptr<WeeklyCompCalculator>& calc : calculators ){
double compHere = calc->calculate( shoePrice, weeklyHours, weeklyUnits );
if( compHere > maxComp ){
maxComp = compHere;
maxDescr = calc->getDescription();
}
}
cout << "Optimal compensation scheme is " << maxDescr << ", weekly comp = " << maxComp << endl;
答案 0 :(得分:2)
派生类构造函数将字符串文字传递给基类:
FixedCompCalculator::FixedCompCalculator() : WeeklyCompCalculator("$600 Weekly")
基类的构造函数将const std::string &
作为其构造函数的参数。
WeeklyCompCalculator(const string&);
因为您的参数实际上是字符串文字,所以构造 临时 std::string
对象,并将对它的引用传递给基类的构造函数。
基类构造函数将其接收的引用作为其参数,并将其保存为其类的成员。
因为类成员最终成为对临时对象的引用,所以只要派生类完成构造(稍早一些,迂腐正确,但这里不相关),临时对象就会被破坏,而基础class最终会引用一个被破坏的对象,并从该点开始使用这个引用导致未定义的行为。
最简单的解决方法是让WeeklyCompCalculator
的类成员成为显式对象实例,而不是引用:
private:
const string description;
};
现在,只要其类的实例存在,description
类成员就会保证存在。