GVKun编程网logo

PHP> 5.4:覆盖具有不同签名的构造函数(php覆盖文件)

7

针对PHP>5.4:覆盖具有不同签名的构造函数和php覆盖文件这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展android-如何在不同的类之间共享相同的构造函数,又在接口中定义构造函数?、

针对PHP> 5.4:覆盖具有不同签名的构造函数php覆盖文件这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展android-如何在不同的类之间共享相同的构造函数,又在接口中定义构造函数?、c – 具有std :: function不同签名的Lambda函数、c – 具有不同签名的类方法专业化、c – 具有不同签名的绑定功能等相关知识,希望可以帮助到你。

本文目录一览:

PHP> 5.4:覆盖具有不同签名的构造函数(php覆盖文件)

PHP> 5.4:覆盖具有不同签名的构造函数(php覆盖文件)

我们知道 PHP不接受带有 different signature than the parent的子方法.我认为构造函数是一样的:PHP文档 states那个

This also applies to constructors as of PHP 5.4. Before 5.4 constructor signatures Could differ.

但是,似乎继承的构造函数在PHP版本中仍然可以不同> 5.4.例如,以下代码不会触发任何警告或通知:

class Something { }
class SomeOtherThing { }

class Foo
{
    public function __construct(Something $foo)
    {
    }

    public function yay()
    {
        echo 'yay';
    }
}

class Bar extends Foo
{
    public function __construct($foo,SomeOtherThing $bar = null)
    {
    }
}

$x = new Bar(new Something());
$x->yay();

根据文档,代码应该触发错误,因为构造函数签名不同.

在PHP 5.6.4上试过这个.与@L_301_3@相同的效果.

那么,那是什么呢?尽管文档说的是什么,不同的构造函数签名仍然合法吗?或者这是一个将在以后的版本中修复的错误?

解决方法

根据 documentation

Unlike with other methods,PHP will not generate an E_STRICT level error message when __construct() is overridden with different parameters than the parent __construct() method has.

所以,这就是为什么你没有得到E_STRICT级别的错误.也许它会触发不同程度的东西.

android-如何在不同的类之间共享相同的构造函数,又在接口中定义构造函数?

android-如何在不同的类之间共享相同的构造函数,又在接口中定义构造函数?

假设我在Android中使用相同的构造函数有多个自定义视图

class Button: AppCompatButton {

    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
    }

    constructor(context: Context) : super(context) {
    }
    //Some custom implementation
    //............
}

class TextView: AppCompatTextView {

    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
    }

    constructor(context: Context) : super(context) {
    }
    //Some custom implementation
    //............
}

所以我需要一些接口或基类,这些接口或基类可以让我继承多个视图,例如TextView,Button,EditText等.

就像是

abstract class BaseView<T : View> : T {
    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
    }

    constructor(context: Context) : super(context) {
    }
}

要么

interface ViewConstructor {
    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
    }

    constructor(context: Context) : super(context) {
    }
}

所以我只使用一个接口或基类,而不是一次又一次地复制过去的承包商.如何在Kotlin中实现这一目标?

附言请不要建议将基类用作View并使用基类创建派生视图.我正在使用XML,因此需要EditText,Button和其他视图.

解决方法:

编辑:我偶然发现了这个答案,它需要更新.在某些自定义视图中,使用@JvmOverloads可能是一个问题,因为调用为您自己的类生成的任何构造函数都将首先委托给该类中的all-params构造函数,然后再调用super的all-params构造函数,而不是每个构造函数以匹配的参数数量调用super方法.有关详细信息,请参见this article(例如).

以下是我的回答的原文.

作为必须编写许多构造函数的解决方案,您可以将默认参数与@JvmOverloads结合使用,以轻松获取所有4个View构造函数,而仅为类编写一个主要构造函数:

class CustomView @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = 0,
        defStyleRes: Int = 0
) : View(context, attrs, defStyleAttr, defStyleRes) {

}

c – 具有std :: function不同签名的Lambda函数

c – 具有std :: function不同签名的Lambda函数

我不明白为什么第三种情况没问题(即使lambda的参数类型与std :: function类型不同),而编译器抱怨第四种情况:
function<int(int)> idInt = [](int i) {return i;}; //OK
function<int(int&)> idInt = [](int &i) {return i;}; //OK
function<int(int&)> idInt = [](int i) {return i;}; //OK
function<int(int)> idInt = [](int &i) {return i;}; //ERROR!

解决方法

当你写:
function<int(int)> idInt = [](int &i) {return i;}; //ERROR!

然后你说idInt可以包装一个函数,闭包,…可以用int参数调用.但是在[](int& i){return i;};的情况下不是这样,因为你不能像这里一样用整数文字调用它:

auto fn = [](int &i) {return i;};
fn(1); // error - you try to bind temporary to reference

您可以通过更改签名来使用右值引用或const&来修复它:

std::function<int(int)> idInt1 = []( int &&i) {return i;};
std::function<int(int)> idInt2 = []( const int &i) {return i;};

c – 具有不同签名的类方法专业化

c – 具有不同签名的类方法专业化

我正在尝试编写一个类模板,其中方法签名会根据模板参数而改变.我的目标是尽可能少地复制代码.考虑这个例子,首先是类声明:

// a.hxx
#ifndef A_HXX
#define A_HXX

template<typename T>
struct A
{
    void foo(T value) const;
    void bar() const;
};

#include <string>

#ifndef short_declaration
template<>
struct A<std::string>
{
    void foo(const std::string &value) const;
    void bar() const;
};
#else // short_declaration
template<>
struct A<std::string>
{
    void foo(const std::string &value) const;
};
#endif // short_declaration

#endif // A_HXX

现在类定义:

// a_impl.hxx
#ifndef A_IMPL_HXX
#define A_IMPL_HXX

#include "a.hxx"
#include <iostream>
#include <typeinfo>

template<typename T>
void A<T>::foo(T value) const
{
    std::cout << "A<T=" << typeid(T).name() << ">::foo(" << value << ")"
        << std::endl;
}

template<typename T>
void A<T>::bar() const
{
    std::cout << "A<T=" << typeid(T).name() << ">::bar()" << std::endl;
}

void A<std::string>::foo(const std::string &value) const
{
    std::cout << "A<std::string>::foo(" << value << ")" << std::endl;
}

#ifndef skip_duplicates
void A<std::string>::bar() const
{
    std::cout << "A<std::string>::bar()" << std::endl;
}
#endif // skip_duplicates

#endif // A_IMPL_HXX

现在是一个测试程序:

// test.cxx

//#define skip_duplicates
//#define short_declaration
#include "a_impl.hxx"

int main(void)
{
    A<int>         obj1;
    A<std::string> obj2;
    int         value1(1);
    std::string value2("baz");

    obj1.foo(value1);
    obj1.bar();

    obj2.foo(value2);
    obj2.bar();

    return 0;
}

如果像这样编译,我得到的预期输出(对于我的typeid实现):

A<T=i>::foo(1)
A<T=i>::bar()
A<std::string>::foo(baz)
A<std::string>::bar()

但我当然喜欢在我的例子中启用skip_duplicates甚至short_declaration的方法.有点similar question,ecatmur回复说需要给出完整的类,所以至少定义short_declaration是行不通的.

其他人如何使用可能将大对象作为参数的方法来处理创建类模板的问题?

解决方法

您可以将重复项提取到基类中:

template<typename T>
struct Base{
    void Bar()
    {
        std::cout << "A<T=" << typeid(T).name() << ">::bar()" << std::endl;
    }

protected:
    ~Base(){}
    template<typename U>
    void DoFoo(U value)
    {
        std::cout << "A<T=" << typeid(T).name() << ">::foo(" << value << ")"
        << std::endl;
    }
};

template<typename T>
struct A : Base<T> {
    void Foo(T value)
    {
        DoFoo(value);
    }
};

template<>
struct A<std::string> : Base<std::string> {
    void Foo(const std::string& value)
    {
        DoFoo(value);
    }
};

c – 具有不同签名的绑定功能

c – 具有不同签名的绑定功能

如果问过这个问题,我道歉.

我以为你不能用不同的签名绑定函数,但看看这个:

void TakesChar(char parameter)
{
    std::cout << parameter << std::endl;
}

using CallSig = void(float);
using CallBack = std::function<CallSig>;

int main()
{
    CallBack callback = std::bind(&TakesChar,std::placeholders::_1);
    callback(1.1f);
    callback(2.2f);

    return 0;
}

编译并运行.您可以尝试不同的参数类型和数字.例如,您可以修改TakesChar,使其不带参数,并且仍然可以编译.

为什么是这样?它背后有理由吗?我可以强制签名完全匹配吗?

谢谢.

解决方法

实际上,这里有两个问题:

>为什么允许转换?
>为什么如果没有提供绑定参数,返回对象是否接受任意数量的参数?

前者只是对bind行为的决定:因为你可以调用TakesChar(1.1f)为什么不允许std :: bind(& TakesChar,_1)绑定到std :: function< void(float)> ?委员会决定允许它.

正如评论中所解释的那样,后者已经在SO上得到解决.简而言之,它不仅更容易,还允许绑定具有多个不同arity的operator()的对象.

关于PHP> 5.4:覆盖具有不同签名的构造函数php覆盖文件的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于android-如何在不同的类之间共享相同的构造函数,又在接口中定义构造函数?、c – 具有std :: function不同签名的Lambda函数、c – 具有不同签名的类方法专业化、c – 具有不同签名的绑定功能等相关知识的信息别忘了在本站进行查找喔。

本文标签: