ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hello, I have this base class and a dreived class...below are the highlights and what not. I'm having trouble accessing the private memebers of the derived class when I use the following code in main:
Code:
int main(){
Vehicle* pArray[3];
pArray[0] = new Vehicle;
pArray[1] = new SUV;
pArray[2] = new SUV;
for(int i = 0; i < 3; i++){
pArray[i]->setMilage(rand());
pArray[i]->display();
pArray[i]->drive();
cout << endl;
} //for
}
I want to be able to set fourWDStatus using an accessor function to true which is found in the SUV derived class by using pArray[1]->...am I doing something wrong or missing something? Below is the code for the two classes:
Code:
class Vehicle{
protected:
int* VIN;
double* milage;
public:
Vehicle() {VIN = new int(NULL); milage = new double(NULL);}
Vehicle(const Vehicle& rhs): VIN(new int()), milage(new double()) {*this = rhs;}
Vehicle& operator =(const Vehicle& rhs);
virtual ~Vehicle(){delete VIN, milage;}
int getVIN() const {return *VIN;}
double getMilage() const {return *milage;}
void setVIN(int v) {VIN = new int(v);}
void setMilage(double m) {milage = new double(m);}
virtual void display();
double calcGasUsed(double);
void drive();
};
/////////////////////////////////////////////////////////////
class SUV: public Vehicle{
private:
bool* fourWDStatus;
double* fourWDGasMileage;
public:
SUV() {fourWDStatus = new bool(NULL); fourWDGasMileage = new double(NULL);}
virtual ~SUV() {delete fourWDStatus, fourWDGasMileage;}
int getFourWDStatus() const {return *fourWDStatus;}
double getFourWDGasMileage() const {return *fourWDGasMileage;}
void setFourWDStatus(bool driveStatus) {fourWDStatus = new bool(driveStatus);}
void setFourWDGasMileage(double gasMileage) {fourWDGasMileage = new double(gasMileage);}
virtual void display();
double calcGasUsed(double);
};
If pArray[1]->setFourWDStatus(true); an incorred way, how is it changed? Becuase if I do:
Code:
SUV t;
t.setFourWDStatus(true);
Then it works fine....I dunno...is the constructor the only way?...Thank you =)
I read through your code, but I'm a little confused at your question. The first code block you posted (main(...)), is that code working and compiling properly? Then you go on to talk about calling your set4wdriver() method, which isn't a part of main.
I could be a little rusty on inheritance, and correct me if I'm wrong (I'm just trying to help), but aren't you trying to employ some broken polymorphism below:
Code:
Vehicle* pArray[3];
pArray[0] = new Vehicle;
pArray[1] = new SUV;
pArray[2] = new SUV;
for(int i = 0; i < 3; i++){
pArray[i]->setMilage(rand());
pArray[i]->display();
pArray[i]->drive();
cout << endl;
} //for
I think you should organize your methods a little differently, employing virtual functions:
Code:
class Vehicle
{
...
// this will be overridden by derived classes
virtual void setMilage(...) {
// perform Vehicle-specific milage calculations
}
};
class SUV : public Vehicle
{
...
// override base class setMilage()
virtual void setMilage(...) {
// perform SUV-specific milage calculations
}
};
Now going back to your main() section, you shouldn't need a special function like set4WheelDriveMilage, because polymorphism will take care of calling the right method for you, based on the object type:
Code:
Vehicle* pArray[3];
pArray[0] = new Vehicle;
pArray[1] = new SUV;
pArray[2] = new SUV;
for(int i = 0; i < 3; i++){
pArray[i]->setMilage(rand());
pArray[i]->display();
pArray[i]->drive();
cout << endl;
} //for
This should work as you expect, assuming you declare display() and drive() as virtual functions as well. Since you properly declare your array of pointers as an array of base class pointers, and then you create derived objects on base class pointers, polymorphism will look at the virtual function table and call the right function for you in your for loop.
Post questions/comments on what you think, thats how I'd structure my program but I'm a tiny bit rusty on C++ inheritance.
I think niteshadw's question may be, "why won't the compiler let me call setFourWDStatus() from my base class pointer?" The answer is because your base class does not define that function as a virtual function-- it does not define that function at all!
You would need to cast your pointer to the derived class to make your classes work as they stand now. Depending on your aims, there are several ways to proceed.
One way is to put all the functions you could possible want to call into the base class as virtual functions.
Yes, everything in main() works thus far, but I want to be able to put one of the two SUVs in four wheel drive mode so when its in four wheel drive mode it calculates the gas usage a different way...its just simple code to try to learn iherintance/polymorphsism...so since pArray[1] is a suv, I should be able to see the private memebers of the class, but I only see those that belong to the base class...so basically how can I set the pArray[1] to four wheel drive? Thanks
carl gave you the right answer, just in case you missed it. You need to do something like this:
Code:
((SUV *)pArray[1])->setFourWDStatus(true);
Excuse me if I've messed up the syntax, I don't really know C++ that well. The point is, even though you initialised pArray[1] as an SUV, pArray is declared (earlier) as an array of Vehicle pointers, and the compiler is stopping you from trying to use a Vehicle as a specific subclass. Effectively, you have to tell the compiler "Yes, I really do want to use this Vehicle as an SUV".
Originally posted by niteshadw Yes, everything in main() works thus far, but I want to be able to put one of the two SUVs in four wheel drive mode so when its in four wheel drive mode it calculates the gas usage a different way...its just simple code to try to learn iherintance/polymorphsism...so since pArray[1] is a suv, I should be able to see the private memebers of the class, but I only see those that belong to the base class...so basically how can I set the pArray[1] to four wheel drive? Thanks
OK, basically you're trying to accomplish polymorphism with code like this:
Code:
int main(){
Vehicle* pArray[3];
pArray[0] = new Vehicle;
pArray[1] = new SUV;
pArray[2] = new SUV;
for(int i = 0; i < 3; i++){
pArray[i]->setMilage(rand());
pArray[i]->display();
pArray[i]->drive();
cout << endl;
} //for
}
Specifically, you are expecting C++ to 'do the Right Thing' in your for loop. If you're not trying to accomplish polymorphism thats fine, and nobodies forcing you too, but your code in main IS trying to use it.
First look at your array declaration. Your declaring an array of base class pointers. Then you're initializing 2 of the 3 elements to derived class objects.
If you listen to the advice you're given, and learn a little about polymorphism theres no need for functions like 'setFourWheelDriveMilage' and that kind of class-specific stuff, and if you code you're base classes right you can save alot of typing.
Heres a very simple example of polymorphism:
Code:
class Vehicle
{
protected:
float milage_;
public:
Vehicle(float m = 10000.00): milage_(m) {}
virtual void print() const {
cout << "I am a Vehicle object\n";
}
};
class SportsCar : public Vehicle
{
protected:
string color_;
public:
SportsCar(float m = 10000.00, string c = ""): Vehicle(m), color_(c) {}
virtual void print() const {
cout << "I am a SportsCar object\n";
}
};
int main()
{
Vehicle* t[2];
t[0] = new Vehicle;
t[1] = new SportsCar;
for(int i = 0; i < 2; i++)
t[i]->print();
return 0;
}
Code:
[shell]$ g++ -o vehicles vehicles.cpp
[shell]$ ./vehicles
I am a Vehicle object
I am a SportsCar object
Take a quick look at the classes, then take a bigger look at the bold red code. How does C++ know which function to call? How does it know whether its operating on a SportsCar or a Vehicle? It calls the right function... How does it do it?
The answer is virtual function tables and polymorphism. I won't try and act like Bjarne, and define polymorphism for you, plenty of C++ books do that for you. But the point is, by declaring those class methods virtual, C++ then knows where to look to determine which function gets called.
If you don't care about any of that, why don't you just write your code the 'normal' way?
Code:
Vehicle* t = new Vehicle;
SUV* s = new SUV;
// ...
Anyway I hope you learned something because it took a while to type. Enjoy.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.