#include<iostream>
namespace vendor1 {
struct IResolveCat {
virtual void resolve() =0;
virtual ~IResolveCat()
{
}
};
void explain(IResolveCat& resolver)
{
resolver.resolve();
}
} // namespace vendor1
namespace vendorB {
struct IResolveDog {
virtual void resolve() =0;
virtual ~IResolveDog()
{
}
};
void explain(IResolveDog& resolver)
{
resolver.resolve();
}
}// namespace vendorB
namespace my_namespace {
struct IResolveCat: public vendor1::IResolveCat {
virtual void resolve()
{
resolveCat();
}
virtual ~IResolveCat()
{
}
protected:
virtual void resolveCat() =0;
};
struct IResolveDog: public vendorB::IResolveDog {
virtual void resolve()
{
resolveDog();
}
virtual ~IResolveDog()
{
}
protected:
virtual void resolveDog() =0;
};
class Resolver: public virtual IResolveCat, public virtual IResolveDog {
protected:
virtual void resolveCat();
virtual void resolveDog();
};
void Resolver::resolveCat()
{
std::cout << "I'm a CAT resolved by Resolver" << std::endl;
}
void Resolver::resolveDog()
{
std::cout << "I'm a DOG resolved by Resolver" << std::endl;
}
} //namespace my_namespace
int main(int args, char** argv)
{
my_namespace::Resolver resolver;
vendor1::explain(resolver);
vendorB::explain(resolver);
return 0;
}
Ну вообще-то, в твоём примере, речь идёт больше о множественном наследии нежели об интерфейсах.WMix, компилировал gcc 4.7.2 из пакетов Ubuntu.
Код:#include<iostream> namespace vendor1 { struct IResolveCat { virtual void resolve() =0; virtual ~IResolveCat() { } }; ..... }
<?php
namespace {
ini_set('display_errors', 1);
error_reporting(E_ALL | E_STRICT);
class Resolver
{
protected $list = [];
public function __get($name)
{
if (isset($this->list[$name]))
{
return $this->list[$name];
}
throw new \Exception($name);
}
}
}
namespace vendorA
{
class IResolveCat
{
public function resolve()
{
$this->resolveCat();
}
protected function resolveCat()
{
}
}
/*
* или вместо \Resolver какой-нибудь IResolver,
* чтобы не завязываться на конкретный класс
*/
function explain(\Resolver $resolver)
{
//то, что ты в примере C++ прописал тип в параметре
//и компилятор выдернул нужную структуру
//здесь получаем её сами
/** @var IResolveCat $cat */
$cat = $resolver->{'IResolveCat'}; //или типа $resolve->getByName($name)
$cat->resolve();
}
} // namespace vendorA
namespace vendorB
{
class IResolveDog
{
public function resolve()
{
$this->resolveDog();
}
protected function resolveDog()
{
}
}
function explain(\Resolver $resolver)
{
/** @var IResolveDog $dog */
$dog = $resolver->{'IResolveDog'};
$dog->resolve();
}
} // namespace vendorB
namespace my_namespace
{
class IResolveCat extends \vendorA\IResolveCat
{
protected function resolveCat()
{
echo 'Cat';
}
}
class IResolveDog extends \vendorB\IResolveDog
{
protected function resolveDog()
{
echo 'Dog';
}
}
class Resolver extends \Resolver
{
public function __construct()
{
$this->list['IResolveCat'] = new IResolveCat;
$this->list['IResolveDog'] = new IResolveDog;
}
}
} //namespace my_namespace
namespace {
$resolver = new \my_namespace\Resolver;
\vendorA\explain($resolver);
\vendorB\explain($resolver);
}
<?php
class Dog{
public function resolve( IResolveDog $resolver ){
$resolver->resolveDog();
}
}
class Cat{
public function resolve( IResolveCat $resolver ){
$resolver->resolveCat();
}
}
interface IResolveDog{
public function resolveDog();
}
interface IResolveCat{
public function resolveCat();
}
class Resolver implements IResolveDog, IResolveCat{
public function resolveCat(){
echo "I'm a CAT resolved by Resolver";
}
public function resolveDog(){
echo "I'm a DOG resolved by Resolver";
}
}
$cat = new Cat;
$dog = new Dog;
$cat->resolve( new Resolver );
$dog->resolve( new Resolver );
В С++ нет интерфейсов, но есть "чисто виртуальные методы", которые не предоставляют реализации. Фактически же структура с набором чисто виртуальных методов -- это в точности интерфейс.множественное наследование
Базовый класс, можно заменить на понятный им общий интерфейс, или вообще убрать тип, оставив просто "$resolve", всё таки мы не ограничены типитизацией параметров.riff, в PHP примере есть существенное отличие от примера на C++: функции vendorA::explain и vendorB::explain принимают базовый \Resolver, который может быть им не известен.
void explain(IResolveCat& resolver)
void explain(IResolveDog& resolver)
Ну извини, уж как смог близко по смыслу перевёл твой пример. То, что "структура в C++ -- это в точности интерфейс" -- это ваш(сишников) плюс, а за рамки того что есть в php, перейти не могу, класс он и остаётся классомВ С++ нет интерфейсов, но есть "чисто виртуальные методы", которые не предоставляют реализации. Фактически же структура с набором чисто виртуальных методов -- это в точности интерфейс....
Нет, совершенно другое.у тебя тоже самое
Нет. То, что у меня в main не выполняется в вашем коде. Explain требует два различных интерфейса, которые содержат одинаковый метод. У Вас методы разные.то что у тебя выполняется в main, выполняется и у меня остальное это внутренняя реализация
namespace Mars {
interface IResolver {
/**
*/
public functon resolve();
};
/**
* @param IResolver
*/
function doResolve(IResolver $resolver)
{
$resolver->resolve()
}
} //namespace Mars
namespace Venus {
interface IResolver {
/**
*/
public functon resolve();
};
/**
* @param IResolver
*/
function doResolve(IResolver $resolver)
{
$resolver->resolve()
}
} //namespace Venus
Тебя уволить и нанять нормального разработчика.Есть необходимость одну и туже сущность передавать и в \Mars\doResolve, и в \Venus\doResolve.
Как это сделать?
$cat = new Cat;
$dog = new Dog;
$cat->resolve( new Resolver );
$dog->resolve( new Resolver );