我想修改构造函数以使用初始化列表,如下例所示:
class Foo
{
public:
Foo(std::wstring bar);
private:
std::wstring bar;
};
// VERSION 1:
Foo::Foo(std::wstring bar) {this->bar = bar}
// VERSION 2:
Foo::Foo(std::wstring bar) : this->bar(bar) {} // ERROR!
Run Code Online (Sandbox Code Playgroud)
不幸的是我不能做版本2,因为你不能使用this数据成员的指针,因为(我猜)它们当时还不存在。那么,我该如何处理名称隐藏问题(即我的参数和我的数据成员具有相同的名称)?
请考虑以下代码段:
struct S
{
S( const int a )
{
this->a = a; // option 1
S::a = a; // option 2
}
int a;
};
Run Code Online (Sandbox Code Playgroud)
选项1是否等同于选项2?是否存在一种形式比另一种形式更好的情况?标准的哪个条款描述了这些选项?
我最近在cppreference 中看到了这段代码:
string str="global scope";
void main()
{
string str="main scope";
if (true){
string str="if scope";
cout << str << endl;
}
cout << str << endl;
}
Run Code Online (Sandbox Code Playgroud)
哪个输出:
if scope
main scope
Run Code Online (Sandbox Code Playgroud)
这很好,我了解整个嵌套作用域的事情,并且我知道当堆栈在语句末尾展开它时, if 作用域内的“str”将被销毁,因此此后它将不可用,因此第二个print 将主“str”作为其参数。
但是,我知道主“str”实际上在 IF 内部可用,或者至少应该是,但问题是如何从 IF 语句内部访问主“str”?
我如何从 main 和/或 if 内部访问全局“str”?
我知道使用不同的名称会更简单,但这个问题不是为了特定的实际应用,而是为了更好地理解 c++ 范围。
我正在尝试从Haskell模块中导出一个名称的子集,但是ghci很高兴让我访问隐藏的名称.
module Hiding (shown, calc) where
calc = shown * hidden
shown :: Int
shown = 3
hidden :: Int
hidden = 2
Run Code Online (Sandbox Code Playgroud)
但是当我在ghci中尝试这个时,我得到:
Prelude> :l Hiding.hs
[1 of 1] Compiling Hiding ( Hiding.hs, interpreted )
Ok, modules loaded: Hiding.
*Hiding> hidden
2
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
(编辑:为了它的价值,我在Arch Linux上使用ghci 6.12.3)
我想定义一个类,它继承了一堆类,但不隐藏这些类的某些特定方法。
想象一下下面的代码:
template<typename... Bases>
class SomeClass : public Bases...
{
public:
using Bases::DoSomething...;
void DoSomething(){
//this is just another overload
}
};
Run Code Online (Sandbox Code Playgroud)
现在的问题是,如果只有一个类没有具有该名称的成员,DoSomething我会收到错误。我已经尝试过使用宏和 SFINAE 来模拟“如果未定义则忽略”,但要处理所有情况,这会变得非常大且丑陋!你有什么办法解决这个问题吗?
如果我可以定义:“嘿使用 - 忽略缺失的成员”,那就太好了。
这里我有一些示例代码:Godbolt
我正在学习使用Java查找名称,并且来自C++我发现有趣的是,即使Java让我嵌套了很多代码块,我也只能在第一个嵌套作用域中隐藏名称:
// name hiding-shadowing: local variables hide names in class scope
class C {
int a=11;
{
double a=0.2;
//{
// int a; // error: a is already declared in instance initializer
//}
}
void hide(short a) { // local variable a,hides instance variable
byte s;
for (int s=0;;); // error: s in block scope redeclares a
{
long a=100L; // error: a is already declared in (method) local scope
String s; //error: s is alredy defined in (method) local …Run Code Online (Sandbox Code Playgroud) 据我所知,我知道这不是关于这个问题的第一个问题,但我读到的所有其他相关问题(和答案)都略显不合适.拿代码
#include <iostream>
using namespace std ;
class Base {
public:
void methodA() { cout << "Base.methodA()" << endl ;}
};
class Derived : public Base {
public:
void methodA(int i) { cout << "Derived.methodA(int i)" << endl ;}
};
int main()
{
Derived obj;
obj.methodA();
}
Run Code Online (Sandbox Code Playgroud)
使用最新版本的g ++编译此代码会产生错误
no matching function for call to 'Derived::methodA()'
Run Code Online (Sandbox Code Playgroud)
正是因为这个错误,我才想到Stackoverflow找到答案.但是没有一个答案对我有说服力.这两种方法的签名在区分它们时没有任何歧义,编译器应该能够在基类中获取方法.只是评论出来
class Derived : public Base {
//public:
// void methodA(int i) { cout << "Derived.methodA(int i)" << endl ;}
};
Run Code Online (Sandbox Code Playgroud)
并且代码按预期工作.这意味着它只是成员函数名称在基类中隐藏相同的名称成员函数,并且不考虑签名,例如函数名称没有被修改(在这种情况下,修改应该解决任何歧义).其他一些人在一个类似的问题中写道,这违背了C++的精神(以及我添加的面向对象),我完全赞同他.这是函数重载的限制,我真的看不出任何合理的原因.
显然问题已经关闭,所以除了编辑我自己的初始问题之外,我无法在阅读答案后添加回复.我相当肯定(但我不能证明它)在旧的C++编译器中,我的初始问题中的代码将编译(然后执行)没有问题.我的观点是,我真的没有看到语言设计背后的理由(正如在回复中所说的那样).在这种情况下,编译器可以获取所有信息以便采取适当的操作,这就是我所期望的.否则看起来,通过语言设计选择,它被选择不考虑成员函数的签名,这听起来很奇怪.我在上面指出的"programmerinterview"中读到了这篇文章,
#include<iostream>
using namespace std;
class ParentClass {
public:
virtual void someFunc(int a){
printf(" ParentClass :: someFunc (int) \n");
};
virtual void someFunc(int* a){
printf(" ParentClass :: someFunc (int*) \n");
};
};
class ChildClass : public ParentClass {
public:
virtual void someFunc(int* a){
printf(" ChildClass :: someFunc(int*) \n");
};
};
int main(){
ChildClass obj;
/* This function call results in an error: */
obj.someFunc(7);
}
Run Code Online (Sandbox Code Playgroud)
第一个给出错误
tr2.cpp: In function 'int main()':
tr2.cpp:27:19: error: invalid conversion from 'int' to 'int*' [-fpermissive]
obj.someFunc(7); …Run Code Online (Sandbox Code Playgroud) name-hiding ×8
c++ ×7
this ×2
c++17 ×1
c++20 ×1
constructor ×1
ghci ×1
haskell ×1
inheritance ×1
java ×1
module ×1
nested ×1
scope ×1