我需要启动父类还是只启动子类

Posted

技术标签:

【中文标题】我需要启动父类还是只启动子类【英文标题】:Do I need to initiate parent class or just child class 【发布时间】:2019-02-08 12:44:51 【问题描述】:

我是编程新手,我正在使用父类fruit 和子类apple 和pear 分析代码。在这个例子中,有一个指向父类的指针。扩展此代码后,我发现使用对象我可以访问父公共成员和所有子成员。问题是我为什么需要这些指针?

// are this pointer needed since I can use j.setWeight(11)

#include <iostream>

using namespace std;

class fruit 
private:
    int weight;

public:
    void setWeight(int x)
    
        weight = x;
    
    int getWeight()
    
        return weight;
    
;

class apple : public fruit 
public:
    void eat()
    
        cout << "Now I am eating apple"
             << "=" << getWeight() << endl;
    
;

class pear : public fruit 
public:
    void eat()
    
        cout << "Now I am eating pear"
             << " = " << getWeight() << endl;
    
;

int main()

    apple j;
    pear k;
    fruit* fruit1 = &j;
    fruit* fruit2 = &k;
    k.setWeight(5);
    k.eat();
    fruit1->setWeight(11);
    apple apple;
    apple.postaviTezinu(16);
    apple.jelo();

    return 0;


are this pointers needed since I can use j.setWeight(11) and results is same as 
fruit1 -> setWeight(11) ... what s difference, thx

【问题讨论】:

我认为你需要更深入地研究多态性虚函数。并考虑您没有直接访问实际对象的情况(例如将fruit* 作为参数传递给函数)。 不,您不需要刚刚发布的代码中的指针。我想问题是为什么你认为指针可能是必要的。您可能正在尝试了解多态性,但您发布的代码不使用多态性,因此不需要指针。 也许作为练习写一个 eat_some_fruit(fruit&amp;); 函数,你可以传递任何水果,这可能会更清楚 此代码无法为我编译。除了未翻译的函数名称之外,apple apple; 也会编译,但这是一个真的坏主意。 【参考方案1】:

我怀疑您正在查看的代码是为了演示如何将指向基类的指针与派生类的对象一起使用。不,本学习练习的功能不需要指针。事实上,这可能是选择此功能的原因。既然您看到了如何在没有指针的情况下完成相同的事情,那么您应该更容易将指针与您已经知道的内容联系起来。

我在这个练习中看到的关键学习点是

    相同的指针类型 (fruit *) 可以指向不同类型的对象(applepear)。 使用基类指针时,可以访问基类成员。 使用指向基类的指针时,不能访问派生类成员。 (隐含的省略;比较 k 所做的事情与 fruit1 所做的事情。)

您将需要继续学习更高级的课程,以了解指针何时比直接访问对象更有用(可能在 eat() 变成虚函数之后)。现在,只需了解如何通过不同方式完成相同的任务。

(当然,您可以在此处获得该信息,但该代码看起来像是一个系列的一部分。继续该系列可能是更好的学习方式。)

【讨论】:

我了解了虚函数,现在我可以使用指针来访问继承类的成员函数,如果我理解正确,我可以定义默认函数行为:) 如果未定义此函数在继承的类中。【参考方案2】:

由于您是编程新手,在这个阶段学习多态对您来说可能有点高级。直接回答您的问题:不,您的示例代码中不需要指针,它们也没有任何帮助。

但是,指向对象的指针通常用于:

减少不必要的对象复制 在多态性(如您的示例中)的情况下,指针在您不知道正在处理的对象类型或不想以不同方式处理它们的程序部分提供帮助

例子:

#include <iostream>
#include <vector>

class A

public:
    virtual void foo ()
    
        std::cout << " I am A\n";
    
;

class B : public A

public:
    virtual void foo ()
    
        std::cout << " I am B\n";
    
;

void bar ( const std::vector <A*> & obj )

    // Here it outputs the foo () function that is
    // appropriate for the class
    for ( unsigned int i = 0; i < obj . size (); ++i )
        obj [i] -> foo ();


int main ()

    A a1, a2, a3;
    B b1, b2, b3;

    // the below input style requires C++11,
    // otherwise input them one-by-one
    std::vector <A*> array &a1, &b1, &a2, &a3, &b2, &b3;

    bar ( array );

    return 0;

上面的array可以存储任何A对象,包括继承的对象(没有指针是做不到的);并且bar 函数仍然可以对数组中的元素执行操作,而无需知道它们在继承树中属于哪个对象类型(由于虚函数)。这对于利用多态性以及一般而言节省函数和代码的重复至关重要。

【讨论】:

以上是关于我需要启动父类还是只启动子类的主要内容,如果未能解决你的问题,请参考以下文章

[Java] 父类和子类拥有同名的成员变量(fields)的情况

Delphi的类和对象- 继承

Java中的抽象类abstract

java父类调用被子类重写的方法

关于Java中子类调用父类方法

我是不是需要将 RowVersion TimeStamp 类型属性“Entity Framework Code First”添加到父类和子类?