从基指针复制派生 class 的构造函数
Copy constructor for derived class from base pointer
我环顾四周,找不到我问题的答案。我正在尝试使用从基数 classes 的指针数组派生的 class 的复制构造函数。我学到的唯一一件事是我可能应该使用 dynamic_cast 但无法正常工作。
到目前为止,这是我的代码的重要部分(原始代码太大了,因为我有 16 个不同的文件,但这应该足够了)。
编辑:我收到的错误是 |26|error: cannot dynamic_cast '& properties[0]' (of type 'class Property**') to type 'class Commercial*' (源不是指向 class 的指针)|
#include "rentals.h"
#include "commercial.h"
#include "sales.h"
#include "comSales.h"
#include "resSales.h"
#include "resRentals.h"
#include "comRentals.h"
const int MAX_PROPERTIES = 5;
int main(void) {
int i;
Property *properties[MAX_PROPERTIES];
properties[0] = new Commercial("Notting Hill McDonalds", "4 Gardiner Road",
"Notting Hill", 5000, "Li3000");
properties[1] = new ResRentals("Janet Dalgleish", "30 Firhill Court",
"Mary Hill", 4000, 500.00, 300.00, 4);
properties[2] = new Commercial(dynamic_cast<Commercial*>(properties[0])); // <-- the copy constructor I can not get to work.
delete[] properties;
return 0;
}
commercial.cpp 文件
#include "property_a.h"
#include "commercial.h"
Commercial::Commercial() : Property() {
owner = "NULL";
address = "NULL";
suburb = "NULL";
postcode = 0;
license = "NULL";
}
Commercial::Commercial(string theOwner, string theAddress,
string theSuburb, int thepostCode,
string theLicense): Property(theOwner, theAddress,
theSuburb, thepostCode), license(theLicense) {}
Commercial::~Commercial() {}
Commercial::Commercial(const Commercial& orig) : Property(orig),
license(orig.getLicense()) {}
void Commercial::print() {
cout << getOwner() << endl;
cout << getAddress() << endl;
cout << getSuburb() << endl;
cout << getPostcode() << endl;
cout << getLicense() << endl;
}
commercial.h 文件
#ifndef __COMMERCIAL_H__
#define __COMMERCIAL_H__
#include "property_a.h"
class Commercial : public virtual Property
{
protected:
string license;
public:
Commercial();
Commercial(string theOwner, string theAddress, string theSuburb,
int thepostCode, string theLicense);
~Commercial() ;
Commercial(const Commercial& orig);
void input() ; // Data input for a Shop object
void print() ; // Data output for a Shop object
string getLicense() const {return license;}; //Note the use of const
void setLicense(string theLicense) {license = theLicense;};
};
property_a.cpp 文件
#include "property_a.h"
Property::Property(){
owner = "NULL";
address = "NULL";
suburb = "NULL";
postcode = 0;
}
Property::Property(string theOwner, string theAddress,
string theSuburb, int thepostCode):
owner(theOwner), address(theAddress),
suburb(theSuburb), postcode(thepostCode){}
Property::~Property() {}
Property::Property(const Property& orig) :
owner(orig.getOwner()), address(orig.getAddress()),
suburb(orig.getSuburb()), postcode(getPostcode()) {}
property_a.h 文件
#ifndef __PROPERTY_A_H__
#define __PROPERTY_A_H__
/*TODO REQUIRED HEADER FILES AND NAMESPACES*/
#include <string>
#include "utility1.h"
class Property
{
protected:
string owner;
string address;
string suburb;
int postcode;
public:
Property();
Property(string theOwner, string theAddress, string theSuburb, int thepostCode);
virtual ~Property();
Property(const Property& orig);
virtual void input() ; // Data input for a Property object
virtual void print() ; // Data output for a Property object
string getOwner() const {return owner;}; //Note the use of const
string getAddress() const {return address;};
string getSuburb() const {return suburb;};
int getPostcode() const {return postcode;};
void setOwner(string newOwner) {owner = newOwner;};
void setAddress(string newAddress) {address = newAddress;};
void setSuburb( string newSuburb) {suburb = newSuburb;};
void setPostcode(int newPostcode) {postcode = newPostcode;};
};
#endif
我希望这是足够的细节
很高兴看到错误,但看起来您根本没有调用复制构造函数:
new Commercial(dynamic_cast<Commercial*>(properties[0]));
就像打电话一样
Commercial(Commercial * other);
所以你需要
new Commercial(*dynamic_cast<Commercial*>(properties[0]));
properties[2] = new Commercial(dynamic_cast(properties[0])); // <-- the copy constructor I can not get to work.
这是将 properties[0]
转换为 Commercial*
。但这不是您的复制构造函数的签名。因此,你需要 new Commercial(*dynamic_cast<Commercial*>(properties[0]));
.
在这个例子中你可以使用 static_cast<Commercial&>(*properties[0])
因为你 知道 properties[0]
是 Commercial
类型。
但是,一般来说,如果你使用dynamic_cast
,这可能意味着你不确定派生类型是什么,你需要检查NULL
(即转换失败)在取消引用之前。
备选
您可以考虑使用多态 API 来为您解决这个问题。
class Base
{
public:
virtual ~Base() = default;
Base* clone() const = 0;
};
class D1 : public Base
{
public:
virtual ~D1() override = default;
D1* clone() const { return new D1(*this); }
};
class D2 : public Base
{
public:
virtual ~D2() override = default;
D2* clone() const { return new D2(*this); }
};
int main()
{
std::unique_ptr<Base> b1(new D2());
std::unique_ptr<Base> b2(b1->clone());
return 0;
}
我环顾四周,找不到我问题的答案。我正在尝试使用从基数 classes 的指针数组派生的 class 的复制构造函数。我学到的唯一一件事是我可能应该使用 dynamic_cast 但无法正常工作。
到目前为止,这是我的代码的重要部分(原始代码太大了,因为我有 16 个不同的文件,但这应该足够了)。
编辑:我收到的错误是 |26|error: cannot dynamic_cast '& properties[0]' (of type 'class Property**') to type 'class Commercial*' (源不是指向 class 的指针)|
#include "rentals.h"
#include "commercial.h"
#include "sales.h"
#include "comSales.h"
#include "resSales.h"
#include "resRentals.h"
#include "comRentals.h"
const int MAX_PROPERTIES = 5;
int main(void) {
int i;
Property *properties[MAX_PROPERTIES];
properties[0] = new Commercial("Notting Hill McDonalds", "4 Gardiner Road",
"Notting Hill", 5000, "Li3000");
properties[1] = new ResRentals("Janet Dalgleish", "30 Firhill Court",
"Mary Hill", 4000, 500.00, 300.00, 4);
properties[2] = new Commercial(dynamic_cast<Commercial*>(properties[0])); // <-- the copy constructor I can not get to work.
delete[] properties;
return 0;
}
commercial.cpp 文件
#include "property_a.h"
#include "commercial.h"
Commercial::Commercial() : Property() {
owner = "NULL";
address = "NULL";
suburb = "NULL";
postcode = 0;
license = "NULL";
}
Commercial::Commercial(string theOwner, string theAddress,
string theSuburb, int thepostCode,
string theLicense): Property(theOwner, theAddress,
theSuburb, thepostCode), license(theLicense) {}
Commercial::~Commercial() {}
Commercial::Commercial(const Commercial& orig) : Property(orig),
license(orig.getLicense()) {}
void Commercial::print() {
cout << getOwner() << endl;
cout << getAddress() << endl;
cout << getSuburb() << endl;
cout << getPostcode() << endl;
cout << getLicense() << endl;
}
commercial.h 文件
#ifndef __COMMERCIAL_H__
#define __COMMERCIAL_H__
#include "property_a.h"
class Commercial : public virtual Property
{
protected:
string license;
public:
Commercial();
Commercial(string theOwner, string theAddress, string theSuburb,
int thepostCode, string theLicense);
~Commercial() ;
Commercial(const Commercial& orig);
void input() ; // Data input for a Shop object
void print() ; // Data output for a Shop object
string getLicense() const {return license;}; //Note the use of const
void setLicense(string theLicense) {license = theLicense;};
};
property_a.cpp 文件
#include "property_a.h"
Property::Property(){
owner = "NULL";
address = "NULL";
suburb = "NULL";
postcode = 0;
}
Property::Property(string theOwner, string theAddress,
string theSuburb, int thepostCode):
owner(theOwner), address(theAddress),
suburb(theSuburb), postcode(thepostCode){}
Property::~Property() {}
Property::Property(const Property& orig) :
owner(orig.getOwner()), address(orig.getAddress()),
suburb(orig.getSuburb()), postcode(getPostcode()) {}
property_a.h 文件
#ifndef __PROPERTY_A_H__
#define __PROPERTY_A_H__
/*TODO REQUIRED HEADER FILES AND NAMESPACES*/
#include <string>
#include "utility1.h"
class Property
{
protected:
string owner;
string address;
string suburb;
int postcode;
public:
Property();
Property(string theOwner, string theAddress, string theSuburb, int thepostCode);
virtual ~Property();
Property(const Property& orig);
virtual void input() ; // Data input for a Property object
virtual void print() ; // Data output for a Property object
string getOwner() const {return owner;}; //Note the use of const
string getAddress() const {return address;};
string getSuburb() const {return suburb;};
int getPostcode() const {return postcode;};
void setOwner(string newOwner) {owner = newOwner;};
void setAddress(string newAddress) {address = newAddress;};
void setSuburb( string newSuburb) {suburb = newSuburb;};
void setPostcode(int newPostcode) {postcode = newPostcode;};
};
#endif
我希望这是足够的细节
很高兴看到错误,但看起来您根本没有调用复制构造函数:
new Commercial(dynamic_cast<Commercial*>(properties[0]));
就像打电话一样
Commercial(Commercial * other);
所以你需要
new Commercial(*dynamic_cast<Commercial*>(properties[0]));
properties[2] = new Commercial(dynamic_cast(properties[0])); // <-- the copy constructor I can not get to work.
这是将 properties[0]
转换为 Commercial*
。但这不是您的复制构造函数的签名。因此,你需要 new Commercial(*dynamic_cast<Commercial*>(properties[0]));
.
在这个例子中你可以使用 static_cast<Commercial&>(*properties[0])
因为你 知道 properties[0]
是 Commercial
类型。
但是,一般来说,如果你使用dynamic_cast
,这可能意味着你不确定派生类型是什么,你需要检查NULL
(即转换失败)在取消引用之前。
备选
您可以考虑使用多态 API 来为您解决这个问题。
class Base
{
public:
virtual ~Base() = default;
Base* clone() const = 0;
};
class D1 : public Base
{
public:
virtual ~D1() override = default;
D1* clone() const { return new D1(*this); }
};
class D2 : public Base
{
public:
virtual ~D2() override = default;
D2* clone() const { return new D2(*this); }
};
int main()
{
std::unique_ptr<Base> b1(new D2());
std::unique_ptr<Base> b2(b1->clone());
return 0;
}