重载以结构继承作为参数的函数 C++
Overloading functions with struct inheritance as arguments c++
我有以下结构继承:
struct Base
{
Base(int a, int b)
: m_a(a), m_b(b)
{
// empty
}
int m_a;
int m_b;
};
struct ChildOne: public Base
{
ChildOne(int a, int b)
: Base(a, b)
{
// empty
}
};
struct ChildTwo: public Base
{
ChildTwo(int a, int b)
: Base(a, b)
{
// empty
}
};
如果我想要一个重载函数,一个处理传递 ChildOne 结构时的情况,一个处理 ChildTwo,我将如何实现它?
我目前正在尝试的是:
在 hpp:
class MyClass
{
void foo(Base s);
}
在 cpp 中:
void Myclass::foo(ChildOne s)
{
//Do things specific for ChildOne
}
void MyClass::foo(ChildTwo s)
{
//Do things specific for ChildTwo
}
如果我对继承的理解正确的话,ChildOne和ChildTwo都是Base。我应该能够将 ChildOne 传递给这个 foo 函数,因为 ChildOne 是一个 Base。但这并没有为我编译,说它无法在 MyClass 中找到匹配的原型(但它 确实 将 foo(Base) 识别为潜在候选者)。我对重载函数和继承有什么误解?
注意:我有一个基 class 并有空子继承它的原因是我可以有一个 std::queue<Base>
只包含 ChildOne 或 ChildTwo 结构,没有 Base 结构。这很好用。它正在调用一个重载函数来处理队列的前面的项目(无论是 ChildOne 还是 ChildTwo),这就是问题所在。
如果您希望 ChildOne 和 ChildTwo 有一个成员函数,您还必须声明 zwo 成员函数(一个用于 childOne,一个用于 ChildTwo)。
就函数重载而言,它是完全无关紧要的,例如ChildOne 派生自 Base。函数声明和定义必须完全匹配。
C++ 在将函数定义与现有声明匹配等情况下不考虑继承。您已经声明了 void foo(Base s);
并且应该只定义它。但是因为你需要重载,你应该有两个声明:
void foo(ChildOne s);
void foo(ChildTwo s);
此外,您可以有 void foo(T s);
重载,其中 T
是对 Base
或 const Base
的指针或引用。当传递不同于 ChildOne
和 ChildTwo
.
的 Base
或派生的 类 时将调用此重载
编辑:
在阅读了我跳过的注释部分后,无法使用 std::queue<Base>
的元素进行上述操作,这些元素都是 Base
。如果您尝试在 ChildOne
或 ChildTwo
中 push
,该对象将获得 sliced.
如果您有 std::queue<Base*>
或 std::queue<std::shared_ptr<Base>>
支持多态性,*myQueue.front()
仍会尝试匹配以 Base
作为参数的重载。尽管如此,您还是应该看看多态性,因为我认为这里应该使用多态性。如果您还没有兴趣,我希望这个例子会让您感兴趣。
#include <iostream>
#include <queue>
using std::cout;
using std::endl;
struct Base
{
Base(int a, int b) : m_a(a), m_b(b) {}
virtual ~Base() = default;
virtual void doSomething() = 0; // pure virtual (must be defined by deriving classes)
int m_a;
int m_b;
};
struct ChildOne : public Base
{
ChildOne(int a, int b) : Base(a, b) {}
virtual void doSomething() override
{
cout << "ChildOne doing something" << endl;
}
};
struct ChildTwo : public Base
{
ChildTwo(int a, int b) : Base(a, b) {}
virtual void doSomething() override
{
cout << "ChildTwo doing something" << endl;
}
};
class MyClass
{
public:
void foo(Base *b)
{
b->doSomething(); // polymorphism will take care of calling the right function
}
};
int main()
{
MyClass c;
std::queue<Base*> queue;
queue.push(new ChildOne(1, 2));
queue.push(new ChildTwo(1, 2));
queue.push(new ChildTwo(1, 2));
queue.push(new ChildOne(1, 2));
while(!queue.empty())
{
c.foo(queue.front());
delete queue.front();
queue.pop();
}
}
输出(Coliru):
ChildOne doing something
ChildTwo doing something
ChildTwo doing something
ChildOne doing something
我有以下结构继承:
struct Base
{
Base(int a, int b)
: m_a(a), m_b(b)
{
// empty
}
int m_a;
int m_b;
};
struct ChildOne: public Base
{
ChildOne(int a, int b)
: Base(a, b)
{
// empty
}
};
struct ChildTwo: public Base
{
ChildTwo(int a, int b)
: Base(a, b)
{
// empty
}
};
如果我想要一个重载函数,一个处理传递 ChildOne 结构时的情况,一个处理 ChildTwo,我将如何实现它?
我目前正在尝试的是: 在 hpp:
class MyClass
{
void foo(Base s);
}
在 cpp 中:
void Myclass::foo(ChildOne s)
{
//Do things specific for ChildOne
}
void MyClass::foo(ChildTwo s)
{
//Do things specific for ChildTwo
}
如果我对继承的理解正确的话,ChildOne和ChildTwo都是Base。我应该能够将 ChildOne 传递给这个 foo 函数,因为 ChildOne 是一个 Base。但这并没有为我编译,说它无法在 MyClass 中找到匹配的原型(但它 确实 将 foo(Base) 识别为潜在候选者)。我对重载函数和继承有什么误解?
注意:我有一个基 class 并有空子继承它的原因是我可以有一个 std::queue<Base>
只包含 ChildOne 或 ChildTwo 结构,没有 Base 结构。这很好用。它正在调用一个重载函数来处理队列的前面的项目(无论是 ChildOne 还是 ChildTwo),这就是问题所在。
如果您希望 ChildOne 和 ChildTwo 有一个成员函数,您还必须声明 zwo 成员函数(一个用于 childOne,一个用于 ChildTwo)。
就函数重载而言,它是完全无关紧要的,例如ChildOne 派生自 Base。函数声明和定义必须完全匹配。
C++ 在将函数定义与现有声明匹配等情况下不考虑继承。您已经声明了 void foo(Base s);
并且应该只定义它。但是因为你需要重载,你应该有两个声明:
void foo(ChildOne s);
void foo(ChildTwo s);
此外,您可以有 void foo(T s);
重载,其中 T
是对 Base
或 const Base
的指针或引用。当传递不同于 ChildOne
和 ChildTwo
.
Base
或派生的 类 时将调用此重载
编辑:
在阅读了我跳过的注释部分后,无法使用 std::queue<Base>
的元素进行上述操作,这些元素都是 Base
。如果您尝试在 ChildOne
或 ChildTwo
中 push
,该对象将获得 sliced.
如果您有 std::queue<Base*>
或 std::queue<std::shared_ptr<Base>>
支持多态性,*myQueue.front()
仍会尝试匹配以 Base
作为参数的重载。尽管如此,您还是应该看看多态性,因为我认为这里应该使用多态性。如果您还没有兴趣,我希望这个例子会让您感兴趣。
#include <iostream>
#include <queue>
using std::cout;
using std::endl;
struct Base
{
Base(int a, int b) : m_a(a), m_b(b) {}
virtual ~Base() = default;
virtual void doSomething() = 0; // pure virtual (must be defined by deriving classes)
int m_a;
int m_b;
};
struct ChildOne : public Base
{
ChildOne(int a, int b) : Base(a, b) {}
virtual void doSomething() override
{
cout << "ChildOne doing something" << endl;
}
};
struct ChildTwo : public Base
{
ChildTwo(int a, int b) : Base(a, b) {}
virtual void doSomething() override
{
cout << "ChildTwo doing something" << endl;
}
};
class MyClass
{
public:
void foo(Base *b)
{
b->doSomething(); // polymorphism will take care of calling the right function
}
};
int main()
{
MyClass c;
std::queue<Base*> queue;
queue.push(new ChildOne(1, 2));
queue.push(new ChildTwo(1, 2));
queue.push(new ChildTwo(1, 2));
queue.push(new ChildOne(1, 2));
while(!queue.empty())
{
c.foo(queue.front());
delete queue.front();
queue.pop();
}
}
输出(Coliru):
ChildOne doing something
ChildTwo doing something
ChildTwo doing something
ChildOne doing something