一个类可以重载公共继承接口中也存在的方法吗?这似乎是明确和有用的,但编译器(VC,英特尔,GCC)都抱怨,至少我的建设.以下是一个玩具示例.继承的rebound()函数有两个明确的重载,但这不会编译.如果你重命名任何一个类中的rebound()方法,它工作正常,但如果它们共享相同的成员函数名称(即使它们被不同的参数类型重载!)你会得到一个致命的错误:"函数参数太少呼叫."
解决方法是微不足道的(我只是重命名方法),但我只是想了解这是否是C++限制(以及为什么会这样).
#include
class Bound {
public:
Bound() : x0(0.0), x1(0.0) {};
Bound(double x) : x0(x), x1(x) {};
double width() const {return x1-x0;}
void rebound(const Bound *a, const Bound *b);
private:
double x0, x1;
};
void Bound::rebound(const Bound *a, const Bound *b)
{
if (a && b) {
x0=std::min(a->x0, b->x0);
x1=std::max(a->x1, b->x1);
}
}
class Node : public Bound {
public:
Node(double x) : Bound(x), left(0), right(0) {};
Node(Node *a, Node *b) : left(a), …Run Code Online (Sandbox Code Playgroud) 我正在浏览C#Brainteasers(http://www.yoda.arachsys.com/csharp/teasers.html)并遇到一个问题:这段代码的输出应该是什么?
class Base
{
public virtual void Foo(int x)
{
Console.WriteLine ("Base.Foo(int)");
}
}
class Derived : Base
{
public override void Foo(int x)
{
Console.WriteLine ("Derived.Foo(int)");
}
public void Foo(object o)
{
Console.WriteLine ("Derived.Foo(object)");
}
}
class Test
{
static void Main()
{
Derived d = new Derived();
int i = 10;
d.Foo(i); // it prints ("Derived.Foo(object)"
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我将代码更改为
class Derived
{
public void Foo(int x)
{
Console.WriteLine("Derived.Foo(int)");
}
public void Foo(object o)
{
Console.WriteLine("Derived.Foo(object)");
} …Run Code Online (Sandbox Code Playgroud) 我希望有人能够回答为什么以下不起作用.虽然忍受我,我仍然是一个菜鸟......我只是无法深究为什么以下
using namespace std;
#include <string>
#include <iostream>
class testClass
{
public:
operator char* () {return (char*)"hi";};
operator int () {return 77;};
operator std::string () {return "hello";};
};
int main()
{
char* c;
int i;
std::string s = "goodday";
testClass t;
c = t;
i = t;
s = t;
cout<< "char: " << c << " int: " << i << " string: "<<s<<endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
给我一个编译时错误:
myMain.cpp: In function ‘int main()’:
myMain.cpp:23: error: ambiguous overload for ‘operator=’ …Run Code Online (Sandbox Code Playgroud) 所以这只是我所拥有的大型作业的一小部分,我只是不确定这个的语法.
我有一个名为的基类Vehicle,它有以下成员:int fuelAmt和int fuelUsage)
(我正在使用命名空间std)
我以<<这种方式重载了运算符:
ostream& operator<<(ostream& osObject, const Vehicle& myVehicle)
{
cout << "Fuel Usage Rate: " << myVehicle.fuelUsage << endl
<< "Fuel Amount: " << myVehicle.fuelAmt << endl;
return osObject;
}
Run Code Online (Sandbox Code Playgroud)
然后我这样称呼它:
cout << Vehicle;
Run Code Online (Sandbox Code Playgroud)
结果是(示例):
Fuel Usage Rate: 10;
Fuel Amount: 50;
Run Code Online (Sandbox Code Playgroud)
我也有一个Airplane派生自Vehicle类的类,它引入了一个新成员:int numEngines.
如何<<在Airplane类中重载操作符,以便它首先调用"Vehicle overloaded操作符结果",然后是我告诉<<操作符从派生类打印的结果......所以,这就是我的意思:
我需要它在Airplane类中这样运行:
ostream& operator<<(ostream& osObject, const Airplane& …Run Code Online (Sandbox Code Playgroud) 最小程序:
#include <stdio.h>
#include <type_traits>
template<typename S, typename T>
int foo(typename T::type s) {
return 1;
}
template<typename S, typename T>
int foo(S s) {
return 2;
}
int main(int argc, char* argv[]) {
int x = 3;
printf("%d\n", foo<int, std::enable_if<true, int>>(x));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
1
Run Code Online (Sandbox Code Playgroud)
为什么不给出编译错误?生成模板代码时,功能不会int foo(typename T::type search)和int foo(S& search)签名相同吗?
如果您稍微更改模板函数签名,它仍然有效(正如我所期望的上面的示例):
template<typename S, typename T>
void foo(typename T::type s) {
printf("a\n");
}
template<typename S, typename T>
void foo(S s) {
printf("b\n");
}
Run Code Online (Sandbox Code Playgroud)
然而,这没有,但唯一的区别是一个具有int签名而另一个由第一个模板参数定义. …
在C++ 11中是否有可能重载const char*和字符串文字(const char[])?我们的想法是避免在strlen已知此长度时调用以查找字符串长度.
这个片段打破了G ++ 4.8和Clang ++ 3.2:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
template<typename T, int N>
void length(const T(&data)[N]) {
printf("%u[]\n", N - 1);
}
template<typename T>
void length(const T* data) {
printf("*%u\n", (unsigned)strlen(data));
}
int main() {
length("hello");
const char* p = "hello";
length(p);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
错误(Clang):
test2.cpp:16:3: error: call to 'length' is ambiguous
length("hello");
^~~~~~
test2.cpp:6:6: note: candidate function [with T = char, N = 6]
void length(const …Run Code Online (Sandbox Code Playgroud) clang和gcc都接受以下代码并选择A::operator B*.
struct B
{
};
struct A : B
{
operator A*();
operator B*();
};
A a;
void* x = a;
Run Code Online (Sandbox Code Playgroud)
我对标准的阅读 - 特别是下面用粗体突出显示的句子 - 表明这种转换应该是模棱两可的.
这两个A::operator A*和A::operator B*是重载,因为候选人A*和B*都转换为void*通过一个标准的转换.因为隐含的对象参数A&是唯一的参数,所以只考虑从隐含的对象参数转换为隐含的对象参数的转换序列 - 忽略转换函数产生的类型.在这两种情况下,隐含的对象参数都是初始化表达式的类型A,而隐含的对象参数是A&.如果两个转换序列相同,则无法区分两个候选者.
8.5初始值设定项[dcl.init]
初始化器的语义如下.的目标类型是对象或引用的类型被初始化和源类型是初始化表达式的类型.
- 如果目标类型是[ reference/array/class ...] [已删除的详细信息不适用于此方案]
- 否则,如果源类型是(可能是cv限定的)类类型,则考虑转换函数. 列举了适用的转换函数(13.3.1.5),并通过重载决策(13.3)选择最佳函数.调用如此选择的用户定义转换以将初始化表达式转换为正在初始化的对象.如果转换不能完成或不明确,则初始化是错误的.
13.3.1.5通过转换函数初始化[over.match.conv]
在8.5中指定的条件下,作为非类型对象初始化的一部分,可以调用转换函数将类类型的初始化表达式转换为要初始化的对象的类型.重载分辨率用于选择要调用的转换函数.假设"cv1 T"是要初始化的对象的类型,并且"cv S"是初始化表达式的类型,其中S是类类型,候选函数选择如下:
- 考虑S及其基类的转换函数.那些未隐藏在S和yield类型T中的非显式转换函数或可通过标准转换序列(13.3.3.1.1)转换为类型T的类型是候选函数.对于直接初始化,那些未隐藏在S和yield类型T中的显式转换函数或者可以通过限定转换(4.4)转换为类型T的类型也是候选函数.返回cv限定类型的转换函数被认为是为此选择候选函数的过程产生该类型的cv非限定版本.返回"引用cv2 X"的转换函数返回lvalues或xvalues,具体取决于引用类型,类型为"cv2 X",因此被认为是为此选择候选函数的过程产生X.
参数列表有一个参数,它是初始化表达式.[注意:此参数将与转换函数的隐式对象参数进行比较. …
为什么启动程序后会显示C::Foo(object o)?
using System;
namespace Program
{
class A
{
static void Main(string[] args)
{
var a = new C();
int x = 123;
a.Foo(x);
}
}
class B
{
public virtual void Foo(int x)
{
Console.WriteLine("B::Foo");
}
}
class C : B
{
public override void Foo(int x)
{
Console.WriteLine("C::Foo(int x)");
}
public void Foo(object o)
{
Console.WriteLine("C::Foo(object o)");
}
}
}
Run Code Online (Sandbox Code Playgroud)
我无法理解为什么当你打电话时C :: Foo,选择方法,而object不是int.什么是类B,该方法被标记为覆盖?
在类中C,有两个方法具有相同的名称但参数不同,是否没有重载?为什么不?在父母中重写的方法之一是否重要?它以某种方式禁用过载?
以下是我对java中重载解析的了解:
编译器尝试从给定的重载方法定义解析方法调用的过程称为重载解析.如果编译器找不到完全匹配,则仅通过使用upcast来查找最接近的匹配(从不进行向下转换).
这是一堂课:
public class MyTest {
public static void main(String[] args) {
MyTest test = new MyTest();
Integer i = 9;
test.TestOverLoad(i);
}
void TestOverLoad(int a){
System.out.println(8);
}
void TestOverLoad(Object a){
System.out.println(10);
}
}
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,输出为10.
但是,如果我稍微更改类定义并更改第二个重载方法.
public class MyTest {
public static void main(String[] args) {
MyTest test = new MyTest();
Integer i = 9;
test.TestOverLoad(i);
}
void TestOverLoad(int a){
System.out.println(8);
}
void TestOverLoad(String a){
System.out.println(10);
}
}
Run Code Online (Sandbox Code Playgroud)
输出为8.
我在这里很困惑.如果永远不会使用向下转换,那为什么8会被打印出来呢?没有编译器为什么拿起TestOverLoad这需要方法int作为一个垂头丧气从论证Integer到int?
How to overload a simple local lambda function?
SSE of original problem:
#include <iostream>
#include <map>
void read()
{
static std::string line;
std::getline(std::cin, line);
auto translate = [](int idx)
{
constexpr static int table[8]{ 7,6,5,4,3,2,1,0 };
return table[idx];
};
auto translate = [](char c)
{
std::map<char, int> table{ {'a', 0}, {'b', 1}, {'c', 2}, {'d', 3},
{'e', 4}, {'f', 5}, {'g', 6}, {'h', 7} };
return table[c];
};
int r = translate(static_cast<int>(line[0]));
int c = translate(static_cast<char>(line[1]));
std::cout << r << …Run Code Online (Sandbox Code Playgroud) overloading ×10
c++ ×7
inheritance ×3
c# ×2
templates ×2
c++11 ×1
c++17 ×1
java ×1
lambda ×1
overriding ×1
standards ×1
unboxing ×1