鉴于以下示例,为什么我必须明确使用该语句b->A::DoSomething()而不仅仅是b->DoSomething()?
编译器的重载决议不应该弄清楚我在谈论哪种方法?
我正在使用Microsoft VS 2005.(注意:在这种情况下使用虚拟无效.)
class A
{
public:
int DoSomething() {return 0;};
};
class B : public A
{
public:
int DoSomething(int x) {return 1;};
};
int main()
{
B* b = new B();
b->A::DoSomething(); //Why this?
//b->DoSomething(); //Why not this? (Gives compiler error.)
delete b;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我在这里有一个非常棘手的案例,有泛型和方法重载.看看这个示例类:
public class Test {
public <T> void setValue(Parameter<T> parameter, T value) {
}
public <T> void setValue(Parameter<T> parameter, Field<T> value) {
}
public void test() {
// This works perfectly. <T> is bound to String
// ambiguity between setValue(.., String) and setValue(.., Field)
// is impossible as String and Field are incompatible
Parameter<String> p1 = getP1();
Field<String> f1 = getF1();
setValue(p1, f1);
// This causes issues. <T> is bound to Object
// ambiguity between setValue(.., Object) and setValue(.., Field) …Run Code Online (Sandbox Code Playgroud) 我想打印两个不同的东西,这取决于一个函数是静态调用Foo::print()还是来自一个实例Foo foo; foo.print();
编辑:这是一个绝对不起作用的类定义,已经有几个人回答了.
class Foo {
string bla;
Foo() { bla = "nonstatic"; }
void print() { cout << bla << endl; }
static void print() { cout << "static" << endl; }
};
Run Code Online (Sandbox Code Playgroud)
但是,有没有一种很好的方法来实现这种效果?基本上,我想做:
if(this is a static call)
do one thing
else
do another thing
Run Code Online (Sandbox Code Playgroud)
换句话说,我知道PHP可以检查是否*this定义了变量,以确定是否静态调用该函数.C++是否具有相同的功能?
我在我的重载方法书中找到了两个例子,但它没有清楚地解释为什么它有用:
package keepo;
public class Main{
public static void main(String [] args)
{
int newScore = calculateScore("Tim", 500);
System.out.println("New Score is" + newScore);
calculateScore(75);
}
public static int calculateScore(String playerName, int score){
System.out.println("Player" + playerName +"Has score" + score);
return score * 1000;
}
public static int calculateScore(int score){
System.out.println("Unnamed player scored" + score + "points");
return score * 1000;
}
}
Run Code Online (Sandbox Code Playgroud)
这非常简单,但老实说,这里的方法重载似乎没用,而且它似乎只是为了做到这一点.
本书中的下一个示例实现了方法重载,这似乎更有用,因为该程序计算英尺到厘米,有一种方法可以放入英尺和英寸,还有一种方法可以放英寸.但是,为此制作两个单独的方法似乎同样容易.
话虽如此,这样做有什么好处吗?(我读过这篇文章,但我并不满意.制作新方法似乎同样容易.)
我们都知道你可以根据参数重载一个函数:
int mul(int i, int j) { return i*j; }
std::string mul(char c, int n) { return std::string(n, c); }
Run Code Online (Sandbox Code Playgroud)
你能根据返回值重载一个函数吗?根据返回值的使用方式定义一个返回不同内容的函数:
int n = mul(6, 3); // n = 18
std::string s = mul(6, 3); // s = "666"
// Note that both invocations take the exact same parameters (same types)
Run Code Online (Sandbox Code Playgroud)
您可以假设第一个参数介于0-9之间,无需验证输入或进行任何错误处理.
我正在尝试编写一个包含一些重载方法的C++类:
class Output
{
public:
static void Print(bool value)
{
std::cout << value ? "True" : "False";
}
static void Print(std::string value)
{
std::cout << value;
}
};
Run Code Online (Sandbox Code Playgroud)
现在让我说我调用方法如下:
Output::Print("Hello World");
Run Code Online (Sandbox Code Playgroud)
结果就是这样
真正
那么,为什么,当我定义该方法可以接受布尔值和字符串时,当我传入一个非布尔值时,它是否使用布尔重载?
编辑:我来自C#/ Java环境,对C++来说还是新手!
当我遇到这种特殊情况时,我正在实现同步/异步重载:
当我有一个没有参数或返回值的常规lambda表达式时,它会Run使用Action参数进行重载,这是可预测的.但是当lambda中有一个lambda时,while (true)它会通过Func参数进入重载状态.
public void Test()
{
Run(() => { var name = "bar"; });
Run(() => { while (true) ; });
}
void Run(Action action)
{
Console.WriteLine("action");
}
void Run(Func<Task> func) // Same behavior with Func<T> of any type.
{
Console.WriteLine("func");
}
Run Code Online (Sandbox Code Playgroud)
输出:
动作
功能
那怎么可能呢?有原因吗?
我今天注意到自动装箱有时会导致方法重载分辨率的模糊.最简单的例子似乎是这样的:
public class Test {
static void f(Object a, boolean b) {}
static void f(Object a, Object b) {}
static void m(int a, boolean b) { f(a,b); }
}
Run Code Online (Sandbox Code Playgroud)
编译时,会导致以下错误:
Test.java:5: reference to f is ambiguous, both method
f(java.lang.Object,boolean) in Test and method
f(java.lang.Object,java.lang.Object) in Test match
static void m(int a, boolean b) { f(a, b); }
^
Run Code Online (Sandbox Code Playgroud)
修复此错误很简单:只使用显式自动装箱:
static void m(int a, boolean b) { f((Object)a, b); }
Run Code Online (Sandbox Code Playgroud)
这正确地按预期正确调用第一个重载.
那么为什么重载决策失败了呢?为什么编译器没有自动包装第一个参数,并正常接受第二个参数?为什么我必须明确请求自动装箱?
假设我有两个C#方法的重载版本:
void Method( TypeA a ) { }
void Method( TypeB b ) { }
Run Code Online (Sandbox Code Playgroud)
我用以下方法调用该方法:
Method( null );
Run Code Online (Sandbox Code Playgroud)
调用该方法的哪个重载?我该怎么做才能确保调用特定的重载?
请考虑以下代码:
public class Converter {
public <K> MyContainer<K> pack(K key, String[] values) {
return new MyContainer<>(key);
}
public MyContainer<IntWrapper> pack(int key, String[] values) {
return new MyContainer<>(new IntWrapper(key));
}
public static final class MyContainer<T> {
public MyContainer(T object) { }
}
public static final class IntWrapper {
public IntWrapper(int i) { }
}
public static void main(String[] args) {
Converter converter = new Converter();
MyContainer<IntWrapper> test = converter.pack(1, new String[]{"Test", "Test2"});
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码编译没有问题.但是,如果一个人改变String[],以String...在两个pack签名和 …
overloading ×10
c++ ×4
java ×4
function ×3
c# ×2
generics ×2
.net ×1
autoboxing ×1
boolean ×1
eclipse ×1
javac ×1
lambda ×1
non-static ×1
null ×1
oop ×1
puzzle ×1
resolution ×1
static ×1
string ×1