C ++ возможно ли сделать класс расширенным на один класс и быть одновременно реализацией интерфейса? - PullRequest
2 голосов
/ 16 января 2011

Coluld, вы предоставляете простой пример кода?(извините C ++ nube) и как вызвать функцию из класса, который вы расширяете?

Ответы [ 5 ]

3 голосов
/ 16 января 2011

В C ++ вы можете расширять несколько классов, это называется множественным наследованием.Скорее всего, это то, что вы ищете.Пожалуйста, прочитайте хорошую книгу о множественном наследовании и C ++ (краткое введение: http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr134.htm),, потому что есть много подводных камней и деталей, на которые следует обратить внимание.

Пример множественного наследования:

class A { ... };
class B { ... };
class C: public A, public B {};  // C inherits from A and B.
3 голосов
/ 16 января 2011

Немного полезный пример:: -)

class CImplementation
{
public:
void doFoo();
};

void CImplementation::doFoo()
{
//implementation
}

class IInterface
{
public:
virtual void foo()=0;
};

class DerivedFromImplementationAndInterface : public CImplementation, public IInterface
{
virtual void foo();
};

void DerivedFromImplementationAndInterface::foo()
{
doFoo();
}


//possible usage:
void method(IInterface& aInterface)
{
aInterface.foo();
}

void test()
{
IInterface* d = new DerivedFromImplementationAndInterface;
method(*d);
}
2 голосов
/ 16 января 2011

C ++ явно не имеет интерфейсов, эквивалент интерфейса в Java обычно реализуется с классом, имеющим только чисто виртуальные функции (плюс конструкторы, деструктор, назначение копирования):

#include <iostream>

// interface
class Fooable {
  public:
    virtual int foo() = 0;
    virtual ~Fooable() {}
};

// base class
class Base {
  public:
    void non_virtual_function() { std::cout << "Base::non_virtual_function\n"; }
    virtual void virtual_function() { std::cout << "Base::virtual_function\n"; }
};

// derived class, inherits from both Base "class" and Fooable "interface"
class Derived: public Base, public Fooable {
  public:
    virtual int foo() {
      // call base class function
      Base::non_virtual_function();
      // virtual call to function defined in base class, overridden here
      virtual_function();
    }
    virtual void virtual_function() {
        // call base class implementation of virtual function directly (rare)
        Base::virtual_function();
        std::cout << "Derived::virtual_function\n";
    }
    void non_virtual_function() {
        // not called
        std::cout << "Derived::non_virtual_function\n";
    }
};

int main() {
    Derived d;
    d.foo();
}
1 голос
/ 16 января 2011

Вопрос, как указано,

C ++, возможно ли заставить класс расширять один класс и реализовывать другой?

не имеет особого смысла.Ответ на это просто «да».Вы можете получить из любого числа классов: C ++ полностью поддерживает множественное наследование.

Итак, учитывая, что поставленный вопрос не является действительно значимым, по крайней мере возможно, что вы имели в виду , чтобы спросить

C ++ возможно ли заставить класс расширить один класс и тем самым реализовать другой?

Ответ на этот вопрос также да, но он не тривиален.Он включает в себя виртуальное наследование .Что довольно сложно.

Вот пример:

#include <iostream>

void say( char const s[] ) { std::cout << s << std::endl; }

class TalkerInterface
{
public:
    virtual void saySomething() const = 0;
};

class TalkerImpl
    : public virtual TalkerInterface
{
public:
    void saySomething() const
    {
        say( "TalkerImpl!" );
    }
};

class MyAbstractClass
    : public virtual TalkerInterface
{
public:
    void foo() const { saySomething(); }
};

class MyClass
    : public MyAbstractClass
    , public TalkerImpl
{};

int main()
{
    MyClass().foo();
}

Виртуальное наследование гарантирует, что в * имеется только один подобъект типа TalkerInterface1027 * экземпляр.Это имеет некоторые нелогичные последствия.Одна из них заключается в том, что «наследование в реализации» работает, а другая заключается в том, что создание подобъекта базового класса происходит в каждом конструкторе MyClass, а в более общем случае - в самом производном классе.

Cheers &НТН.,

1 голос
/ 16 января 2011

Не уверен, что вы спрашиваете:

class A
{
  public:
    void method();
};

class B
{
  public:
    void method();
};

class C : public A, public B
{
  public:
    void callingMethod();
};

void C::callingMethod()
{
  // Here you can just call A::method() or B::method() directly.
  A::method();
  B::method();
}

Обратите внимание, что множественное наследование может привести к действительно трудно решаемым проблемам, и я рекомендую использовать его только при необходимости.

...