理解OOP关联和函数(c ++)

时间:2017-07-18 12:57:02

标签: c++ oop

对于c ++中的对象和类,仍然有很多我不了解的内容,到目前为止我所读过的内容并没有帮助我理解其中的任何内容,而是我正在慢慢地将信息从我设法完成的练习中拼凑起来。 / p>

几个要点: 从类创建对象时,如何在另一个类的函数中访问该对象的名称?什么类型的变量是存储在的对象的名称?是否甚至在创建后存储在任何地方?

我的手册中有一个创建两个类之间关联的示例;

    Aggregationclass
{
public:
  ...
private:
  Partclass* partobject_;
  ...
};

这究竟意味着什么? Aggregationclass可以访问partclass中的对象partobject吗? partclass中的aggregationclass可以读取哪些变量?

这是我从c ++ OOP介绍类中坚持的练习,期望我利用类之间的关联。 (7(2/2)/ 11)

它由不可编辑的Car类组成;

#include <iostream>
#include <string>
using namespace std;

class Car
{
public:
    void Move(int km);
    void PrintDrivenKm();
    Car(string make, int driven_km);
private:
    string make_;
    int driven_km_;
};

Car::Car(string make, int driven_km) : make_(make), driven_km_(driven_km)
{
}

void Car::Move(int km)
{
    driven_km_ = driven_km_ + km;
    cout << "Wroom..." << km << " kilometers driven." << endl;
}
void Car::PrintDrivenKm()
{
    cout << make_ << " car has been driven for" << driven_km_ << " km" << endl;
}

到目前为止我做了什么(人类);我在本节的评论中写了大部分问题。

class Person //how do I associate Person class with Car class in a way that makes sense?
{
    public:
    void ChangeCar(string);
        Person(string, string);
    int DriveCar(int);

    private:
    Car* make_;         
    Car* driven_km_;

    string name_;
};

Person::Person(string name, string make) //How do I ensure string make == object created from class Car with same name?
{
    Person::name_ = name;
    Car::make_ = make_;
}
int Person::DriveCar(int x) //Is this the correct way to use a function from another class?
{
    Car::Move(x);
}
void Person::ChangeCar(string y) //this function is wrong, how do I create a function that calls for object from another class with the parameter presented in the call for this function (eg. class1 object(ferrari) = class1 object holds the values of object ferrari from class2?)?
{
    Car::make_ = y;
}

和不可编辑的主要();

int main()
{
    Car* dx = new Car("Toyota corolla DX", 25000);
    Car* ferrari = new Car("Ferrari f50", 1500);

    Person* driver = new Person("James", dx);

    dx->PrintDrivenKm();
    driver->DriveCar(1000);
    dx->PrintDrivenKm();

    ferrari->PrintDrivenKm();
    driver->ChangeCar(ferrari);
    driver->DriveCar(20000);
    ferrari->PrintDrivenKm();
    return 0;
}
免责声明:该练习已经翻译成另一种语言,如果发现我没有注意到的翻译错误,请发出通知,我会尽力修复。

完成练习;谢谢,你/ doctorlove花时间回复你,我可以自信地说我学到了很多东西!

    class Person
{
public:
void ChangeCar(Car * y);
    Person(String name, Car * Car);
int DriveCar(int);
private:
Car * Car_;
int x;
string name_;
string y;
};

Person::Person(string name, Car * Car) : name_(name), Car_(Car)
{
  Person::name_ = name;
}
int Person::DriveCar(int x)
{
  Car_->Move(x);
}
void Person::ChangeCar(Car * y)
{
 Car_ = y;
}

1 个答案:

答案 0 :(得分:3)

在谈论指针之前,请查看Car类:

class Car
{
public:
    void Move(int km);
    void PrintDrivenKm();
    Car(string make, int driven_km);
private:
    string make_;
    int driven_km_;
};

你无法从外面找到私人物品。期。 你可以制作(或构建)一个

Car car("Zoom", 42);

因为我们可以看到构造函数的作用

Car::Car(string make, int driven_km) : make_(make), driven_km_(driven_km)
{
}

很明显它将私有成员变量make_driven_km_中的字符串和int保存起来。

现在我们可以在这个实例上调用公共函数:

car.PrintDrivenKm();
car.Move(101);
car.PrintDrivenKm();

所以,我们制造了一辆汽车并调用了一些功能。

我们可以制作汽车指针并调用其功能。我们需要删除内容,否则我们会泄漏。

Car * car = new Car("Zoom", 42);
car->PrintDrivenKm();
car->Move(101);
car->PrintDrivenKm();
delete car;

现在解决你的问题。

您已经开始编写Person课程,其中包含两个(私人)汽车(指针)make_driven_km_。构造函数Person(string, string);接受两个字符串,但main不向它发送两个字符串:

Car* dx = new Car("Toyota corolla DX", 25000);
// ...
Person* driver = new Person("James", dx);

将发送一个字符串和Car *;像这样的东西

Person(string name, Car *car);

所以也许只需要一辆车(指针),Car *car_

现在,至于调用您的汽车指针,CarMove方法;实例方法不是静态方法,所以在实例上调用它:

int Person::DriveCar(int x)
{
    //Car::Move(x);  //no - which car do we move, not a static on ALL cars
    car_->Move(x);
}

现在,如果这个人想要换车,你就会让人拿一个字符串:

void Person::ChangeCar(string y)
{
    //what goes here?
    // you want a Car * from a string...
    //  we did that before
    delete car_; //not exception safe, but ... 
    car_ = new Car(y);
}

回头看mian:

driver->ChangeCar(ferrari);

所以调用代码会尝试发送一个汽车(指针)来交换。所以,让签名正确:

void Person::ChangeCar(Car * y)
{
    car_ = y;
}

如果你拥有指针,你需要一个析构函数来整理指针。 告诉谁设置了main中的代码来删除他们的指针!

编辑:

要重新迭代,您可以在任何Person中调用meber变量car_函数上的方法,例如

void Person::ChangeCar(Car * y)
{
    car_ = y;
    y->PrintDriveKm(); //call a method on a car pointer.
    car_->PrintDriveKm();
}

这与在指针上调用方法的方法相同,如我的答案顶部所述。

返回

Car* dx = new Car("Toyota corolla DX", 25000);
// ...
Person* driver = new Person("James", dx);

从这里开始,您可以致电

dx->PrintDrivenKm();

从Person构造函数内部

Person(string name, Car *car) : name_(name), car_(car)
{
}

您可以在大括号内调用car(或car_)上的方法:

Person(string name, Car *car) : name_(name), car_(car)
{
     std::cout << "Hello, " << name << '\n';
     car_->PrintDrivenKm();
}

值得注意的是:Car::表示类/ structr / namespace / scope Car中的内容 - 但是您想要调用实例方法,因此需要实例名称。对指向实例的指针的所有方法使用->。使用.调用实例上的方法。