根据继承用法,不允许以下哪一项?

时间:2010-09-24 12:07:00

标签: c++

来自here

使用继承,不允许以下哪一项

a)通过子类

更改父级操作的实现

b)通过子类

在父类中实现操作

c)子类使用父类中的属性

d)拥有操作是子类中不存在的子类

e)无

我不相信上述链接中的答案,所以试图澄清一下。请回答。

5 个答案:

答案 0 :(得分:6)

答案是e)无。

答案 1 :(得分:4)

我会说答案是答案。

您无法更改父类中的操作的实现。

您可以覆盖实现(如果操作被声明为virtual),或者您可能能够隐藏原始实现......但从未实际更改基类提供的实现。< / p>

请考虑以下事项:

class Parent
{
    public:
        virtual void sayHello() { count << "Hello World!"; }
}

class Child : Parent
{
    public:
       void sayHello() { cout << "42!"; }
}

现在看一下结果:

// Will still say "Hello World!" because our child can never 
// change the parent's implementation
Parent* parent1 = new Parent();
parent1->sayHello();

答案 2 :(得分:1)

“A”就是答案,这就是为什么......

a - 可以覆盖父操作(在某种意义上替换),但不能更改。

#include <iostream>

class A {
public:
   A() {}
   virtual ~A() {}
   virtual void foo() {
      std::cout << "Hi, I'm A" << std::endl;
   }
};

class B : public A {
public:
   B() {}
   virtual ~B() {}
   virtual void foo() {
      std::cout << "Hi, I'm B" << std::endl;
   }
};

int main() {
   A* a = new B();
   a->foo();

   return 1;
}

上面的代码将打印...

Hello, I'm B

B :: foo()覆盖了A :: foo()但没有改变它。


b - 是的,子类可以使用父类中的方法实现。例如,如果我们将上面代码中的B :: foo()方法更改为...

virtual void foo() {
   A::foo();  // <--------------------------NOTE the addition of this call
   std::cout << "Hi, I'm B" << std::endl;
}

......程序将打印......

Hi, I'm A
Hi, I'm B

c - 子类可以使用父类的公共受保护的属性,但不能使用私有属性。例如:

#include <iostream>

class A {
public:
   A() : pub(1), pro(2), pri(3) {}
   virtual ~A() {}
   virtual void foo() {
      std::cout << "Hi, I'm A" << std::endl;
   }

   int pub;

protected:

   int pro;

private:

   int pri;
};

class B : public A {
public:
   B() {}
   virtual ~B() {}
   virtual void foo() {
      std::cout << pub << std::endl;
      std::cout << pro << std::endl;
      std::cout << pri << std::endl;  // <----COMPILE ERROR
   }
};

int main() {
   A* a = new B();
   a->foo();

   return 1;
}

该代码在上面提到的行上会有编译错误,因为子类B正在尝试访问父类的私有成员。如果另一个类被声明为朋友,则此规则有一个例外,但您应该很少(如果有的话)使用friend关键字。


d - 是的,子类可以具有父类没有的操作。例如:

#include <iostream>

class A {
public:
   A() {}
   virtual ~A() {}
   virtual void foo() {
      std::cout << "Hi, I'm A" << std::endl;
   }
};

class B : public A {
public:
   B() {}
   virtual ~B() {}
   virtual void foo() {
      std::cout << "Hi, I'm B" << std::endl;
   }

   virtual void otherFunc() {
      std::cout << "I'm a function that my parent class doesn't have." << std::endl;
   }
};

int main() {
   B b;
   A& a = b;

   a.foo();
   a.otherFunc();  // <--- COMPILE ERROR

   b.foo();
   b.otherFunc();  // <--- OK

   return 1;
}

在上面的示例中, otherFunc()被添加到子类B中。尝试从对A类的引用中调用它将导致编译错误。在B类上调用它可以按预期工作。


学习和了解的最佳方法是在编译器中尝试这些东西。试试上面的代码。我在Visual Studio 2008中对它进行了测试。未明确标记为COMPILE ERROR的示例应该有效。

答案 3 :(得分:0)

我会说E.我想我看到Justin对A项的评价,但在他的例子中,遗产是一个红色的鲱鱼,我认为他正在寻找一种不存在的技巧。

创建具有覆盖行为的子项不会影响父如果未使用子项,但这似乎不言而喻。如果您更改了Parent的parent1实例以使用子构造函数,我认为您会看到A点将被确认。

答案 4 :(得分:0)

  

使用继承,不允许以下哪项   a)通过子类

更改父级操作的实现

这是不允许的。您可以覆盖虚函数,以便子类对象在通过指针或对基类的引用访问时,运行它们自己的那些函数的实现,但是您无法阻止基类的实例运行其正常实现。 / p>

(从技术上讲,如果基类定义了成员函数模板,你可以定义一个新的特化,它将从定义的角度到该翻译单元的结尾产生影响,但这是一个讨厌的黑客而不是真正的内涵模板)。

  

b)通过子类

在父类中实现操作

这仅适用于公共/受保护的成员 - 而非私人成员。

  

c)子类使用父类中的属性

这仅适用于公共/受保护的成员 - 而非私人成员。

  

d)拥有操作是子类中不存在的子类

这是明确允许的,不可能限制。

因此,a)是最明确的不允许的答案,而b)和c)可以使用基类声明中的访问说明符来允许或禁止。 d)绝对允许。