这个问题已经在这里有一个答案:
- 我什么时候要明确使用`this`指针? 13个回答
我负责的,在整个使用下面的结构大的代码库
class MyClass
{
public:
void f(int x);
private:
int x;
};
void MyClass::f(int x)
{
'
'
this->x = x;
'
'
}
就个人而言,我会一直使用,因此喜欢的形式
class MyClass
{
public:
void f(int x);
private:
int _x;
};
void MyClass::f(int x)
{
'
'
_x = x;
'
'
}
我更喜欢后者的原因是,它是更简洁(更少的代码=较少潜在的错误),并且我不喜欢在同一时间在哪里可以避免它具有在范围相同名称的多个变量。 这就是说,我看到前者的使用越来越频繁,这些天。 有没有上攻到第二个办法,我不知道的? (例如,在编译时的效果,用模板代码等使用...)是两种优势的做法不够显著功德重构其他? 我之所以问,虽然我不喜欢现在的第二种方法中的代码,努力量和相关风险引入进一步的bug不太值得一重构。
Answer 1:
你的版本是有点更干净,但是当你在的话,我会:
- 避免前面的下划线:_x是确定的,直到有人选择_MyField这是保留名称。 初始下划线后跟一个大写字母是不允许作为变量名。 请参阅: 什么是关于一个C ++标识符中使用下划线的规则是什么?
- 使属性为私有或受保护的:如果编译的变化是安全的,你会确保您的二传手将被使用。
- 该这个 - >故事在模板代码中使用,例如使该字段名称取决于你的类型(可以解决一些问题,查找)。
其通过使用一个明确的这 - 固定名称解析的一个小例子>(测试使用g ++ 3.4.3):
#include <iostream>
#include <ostream>
class A
{
public:
int g_;
A() : g_(1) {}
const char* f() { return __FUNCTION__; }
};
const char* f() { return __FUNCTION__; }
int g_ = -1;
template < typename Base >
struct Derived : public Base
{
void print_conflicts()
{
std::cout << f() << std::endl; // Calls ::f()
std::cout << this->f() << std::endl; // Calls A::f()
std::cout << g_ << std::endl; // Prints global g_
std::cout << this->g_ << std::endl; // Prints A::g_
}
};
int main(int argc, char* argv[])
{
Derived< A >().print_conflicts();
return EXIT_SUCCESS;
}
Answer 2:
现场命名无关用代码异味。 正如尼尔说,现场能见度这里唯一的代码异味。
有关于C ++的命名约定各项条款:
- 命名约定为公共和私有变量?
- 私有方法的命名约定
- C ++命名空间的使用和命名规则
等等
Answer 3:
这种用法的“本”是由微软C#编码标准鼓励。 它提供了一个良好的代码的清晰度,并意在超过M_或_或任何成员中其他变量的使用标准。
老实说,我真的不喜欢在名字中强调,无论如何,我用我的所有成员通过一个单一的“M”前缀。
Answer 4:
很多人利用这一点,因为在他们的IDE它将使当前类弹出的标识符的列表。
我知道我在做BCB。
我想你的命名冲突提供的例子是个例外。 在Delphi虽然风格指南使用参数的前缀(通常是“A”),以避免正是这一点。
Answer 5:
我个人的感觉是,战斗现有的编码习惯是东西你不应该这样做。 正如萨特/ Alexandrescu的把它在他们的著作“C ++编码规范”:不出汗的小东西。 任何人都能够读取的一个或另一个,是否有领导“这个 - >”或“_”或什么的。
然而,在命名约定的一致性的东西,你通常都希望,在某个范围内(至少文件范围内,最好在整个代码库,当然),被认为是很好的做法,以便坚持一个约定。 你提到的这种风格在整个较大的代码库中,所以我觉得改装的另一次会议将是相当一个坏主意。
如果你,毕竟,发现有一个很好的理由要改变它,不要做手工。 在最好的情况下,你的IDE支持这些类型的“重构”的。 否则,写一个脚本要改变它。 搜索和替换应该是最后的选择。 在任何情况下,你应该有一个备份(源控制)和某种自动化测试设备。 否则,你会不会有它的乐趣。
Answer 6:
以这种方式使用“这”是IMO不是一个代码味道,但仅仅是一个个人喜好。 因此,不能与代码的系统中的其余部分的一致性一样重要。 如果此代码不一致,你可以改变它相匹配的其他代码。 如果通过改变它,你将介绍不一致与广大的代码的其余部分,这是非常糟糕的,我会独自离开它。
你不希望永远进入打码网球的位置上有人修改的东西纯粹是为了使它看起来“好”只是别人来搭配不同口味谁又换了回来后一起走。
Answer 7:
class MyClass{
public:
int x;
void f(int xval);
};
//
void MyClass::f(int xval){
x = xval;
}
Answer 8:
我总是用M_命名约定。 虽然我一般不喜欢“匈牙利表示法”,我觉得这是非常有用的,看的很清楚,如果我有类成员数据的工作。 另外,我发现使用2名相同的变量名在同一范围内也容易出错。
Answer 9:
我同意。 我不喜欢这样的命名约定 - 我更喜欢一个地方有成员变量和局部变量之间存在着明显的区别。 如果你离开关闭,会发生什么this
?
Answer 10:
在我看来, 这往往杂波添加到代码,所以我倾向于使用不同的变量名(根据约定,它可能是一个下划线,M_,等等)。
Answer 11:
class MyClass
{
public:
int m_x;
void f(int p_x);
};
void MyClass::f(int p_x)
{
m_x = p_x;
}
...是使用范围前缀我的首选方式。 M_为会员,为P_参数(一些使用A_的说法代替),G_全球有时L_本地是否有帮助可读性。
如果你有两个变量应该得到同样的名字,那么这可以帮助了很多,避免了不得不做了一些随机变化上它的意义,只是为了避免重新定义。 或者更糟的是,可怕的 'X2,X3,X4,等' ...
Answer 12:
这是一个在C的正常++有关使用初始化器建设被初始化成员。
要做到这一点,你必须使用一个不同的名称成员变量的名称。
所以,即使我会使用Foo(int x) { this.x = x; }
Foo(int x) { this.x = x; }
在Java中,我不会在C ++。
真正的气味可能是缺乏使用该做的无非就是变异的成员变量,而不是使用其他initialisers和方法的this -> x
本身。
任何人都知道为什么它是普遍的做法在每一个C ++店我一直在使用的构造函数参数的成员变量不同的名称与initialisers使用时? 在那里有些不支持C ++编译器?
Answer 13:
今天,大多数IDE的编辑颜色的变量来表示的局部变量的类成员。 因此,IMO,“这 - >”应该被要求是为了便于阅读既不前缀或。
Answer 14:
我不喜欢用“本”,因为它是返祖现象。 如果你是在良好的老C(还记得C 2)编程,并且要模仿一些OOP的特点,创建几个成员结构(这类似于你对象的属性),并创建一套的功能,这都将一个指针,它指向结构作为其第一个参数(这些是类似于对象的方法)。
(我觉得这个typedef的语法是正确的,但它已经有一段时间...)
typedef struct _myclass
{
int _x;
} MyClass;
void f(MyClass this, int x)
{
this->_x = x;
}
事实上,我相信旧的C ++编译器实际上编译代码上面的格式,然后只将它传递给C编译器。 换言之 - C ++在一定程度上只是语法糖。 所以,我不知道为什么有人想在C ++编程,并返回到明确使用“本”的代码 - 也许是“句法Nutrisweet”
Answer 15:
如果你有一个问题,命名约定,你可以尝试使用类似如下因素。
class tea
{
public:
int cup;
int spoon;
tea(int cups, int spoons);
};
要么
class tea
{
public:
int cup;
int spoon;
tea(int drink, int sugar);
};
我觉得你有这个想法。 它基本上命名变量不同,但在逻辑意义上的“相同”。 我希望它能帮助。
文章来源: Excessive use of `this` in C++ [duplicate]