单例继承类调用成员函数报错。

昆仑道长 2016-02-28 05:17:51
我写了一个单例
class Singleton {
protected static $instance;

protected function __construct() { }

final public static function getInstance() {
if (!isset(static::$instance)) {
static::$instance = new static();
}

return static::$instance;
}

final private function __clone() { }

然后我继承了它

class CApp extends CSingleton{
protected function __construct(){
echo "Enter CApp construct"; //这里可以正常进入,也可以调用非静态成员函数
}
public function InitApp(){
// do something init
}
}

然后,我这么调用

$app = CApp::instance();
$app->InitApp(); // 执行到这一句就报错了,错误是call member function from non-object.

请问怎样正确调用?CApp 应该如何修改?
...全文
172 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
昆仑道长 2016-02-28
  • 打赏
  • 举报
回复
在stackoverflow上我找到了多个子类继承同一个单例,依旧正常工作的例子。 原文链接在此.下面是我复制的源代码, 免得大家看一些不相关的英文评论。

class Singleton
{
    private static $instances = array();
    protected function __construct() {}
    protected function __clone() {}
    public function __wakeup()
    {
        throw new Exception("Cannot unserialize singleton");
    }

    public static function getInstance()
    {
        $cls = get_called_class(); // late-static-bound class name
        if (!isset(self::$instances[$cls])) {
            self::$instances[$cls] = new static;
        }
        return self::$instances[$cls];
    }
}
// 测试例子
class Foo extends Singleton {}
class Bar extends Singleton {}

echo get_class(Foo::getInstance()) . "\n";
echo get_class(Bar::getInstance()) . "\n";
感谢各位版主的精彩回答!
昆仑道长 2016-02-28
  • 打赏
  • 举报
回复
引用 2 楼 xuzuning 的回复:
不过,继续
class CApp1 extends CSingleton{
  protected function __construct(){
    echo "Enter CApp1 construct\n";
  }
}
$app1 = CApp::getinstance();
//$app->InitApp();
print_r($app1);
CApp Object
(
)
就出麻烦了 因为静态属性的原因,继承已无意义了
版主,我发现我实际代码的笔误了,我把
static::$instance=static(); //写成static::$instance==static(); 
//直接把赋值语句变成条件语句了,所以是none-object.
//因为静态属性的原因,继承已无意义了。是什么意思。
//我实际上每个单例派生类都有自己的私有成员和成员函数。
//你上面的代码是不是也有笔误啊?实际应该是
 
$app1 = CApp1::getinstance(); $app1->InitApp();
//这样输出就是CApp1了吧
傲雪星枫 2016-02-28
  • 打赏
  • 举报
回复
两句代码有问题 class CApp extends CSingleton $app = CApp::instance(); 改为 class CApp extends Singleton $app = CApp::getInstance(); 就可以了,估计手误。 完整代码修改后如下:

<?php
class Singleton {
    protected static $instance;
 
    protected function __construct() { }
 
    final public static function getInstance() {
        if (!isset(static::$instance)) {
            static::$instance = new static();
        }
 
        return static::$instance;
    }
 
    final private function __clone() { }
}

class CApp extends Singleton{
            protected function __construct(){
               echo "Enter CApp construct";    //这里可以正常进入,也可以调用非静态成员函数
            }
            public function InitApp(){
                echo 'do sth';
             }
}
$app = CApp::getInstance();
$app->InitApp();
?>
xuzuning 2016-02-28
  • 打赏
  • 举报
回复
不过,继续
class CApp1 extends CSingleton{
  protected function __construct(){
    echo "Enter CApp1 construct\n";
  }
}
$app1 = CApp::getinstance();
//$app->InitApp();
print_r($app1);
CApp Object
(
)
就出麻烦了 因为静态属性的原因,继承已无意义了
xuzuning 2016-02-28
  • 打赏
  • 举报
回复
class CSingleton {
  protected static $instance;
  protected function __construct() { }
  final public static function getInstance() {
    if (!isset(static::$instance)) {
      static::$instance = new static();
    }
    return static::$instance;
  }
  final private function __clone() { }
}

class CApp extends CSingleton{
  protected function __construct(){
    echo "Enter CApp construct\n";
  }
  public function InitApp(){
    echo __METHOD__ . PHP_EOL;
  }
}

$app = CApp::getinstance();
$app->InitApp();
Enter CApp construct
CApp::InitApp

没有问题,php 5.4.31

21,886

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧