C++ 私有成员变量与 ctor params 同名
C++ private member variables same name as ctor params
我知道很多人对私有成员变量名使用前缀或后缀。对于那些没有,但只是使用名称的人 - 如果你想拥有同名的构造函数参数,你如何初始化它们?
您只需在初始化列表中初始化它们:
struct foo
{
foo(int bar) : bar(bar) {}
private:
int bar;
};
请注意,初始化列表是在构造函数中显式初始化成员的唯一方法。一旦进入构造函数的主体,成员就已经被初始化了。
顺便说一句,C++ 允许您在声明时初始化一个成员,在这种情况下,它被初始化为该值,除非在构造函数中另外初始化:
struct foo
{
foo(int bar) : bar(bar) {}
foo() {} // bar initialized to 42
private:
int bar = 42;
};
如果使用初始化列表,只需使用相同的名称,编译器就会理解您的意思。
示例:
Book::Book(std::string title, int year)
: title(title), year(year)
{}
最简单的方法是使用内存初始化器列表。例如
class A
{
private:
int data;
public:
A( int data ) : data( data ) {}
};
如果要在构造函数体内使用数据成员,则有两种方法可以区分数据成员和参数
class A
{
private:
int data;
public:
A( int data ) : data( data )
{
A::data *= data;
this->data *= data;
}
};
通过简单地编写它们。语言规则防止出问题。
struct Foo
{
Foo(int x) : x(x) {};
int x;
};
在()
之外,只有数据成员在范围内;在内部,函数参数 隐藏了 成员,就像在普通函数体中一样:
int x = 2;
void foo(int x)
{
// any access to `x` means the argument
}
这是我在命名数据成员时不使用 m_
前缀样式(或等效样式)的众多原因之一。
方法正式名称的价值不高,考虑到它的范围是多么有限。然而,应该 仍然有动力能够立即区分这些项目 'origins' 一目了然。
这已成为我的习惯
a) 在我的数据属性名称前加上 'm_'、
和
b) 在方法/函数参数名称前加上'a_' 或'an_',始终力求语法正确。
LMBM::Node::Node(uint8_t a_max) : m_max (a_max) ...
void* LMBM::Node::threadEntry(void* an_objPtr) ...
void DV1::processDirent(const std::string& a_dirPath) ...
void DV1::handleDT_REG (DV::Dirent* an_ent,
const std::string& a_path) ...
FInfo (const std::string& aPfn, const int64_t& aFileSz) :
m_pfn (aPfn),
m_fileSz (aFileSz) ...
目标 - 更容易阅读
动机-代码一次编写,多次阅读
我理解 ctor 初始化列表的特殊情况。但我也相信使用前缀(您选择的)确实有助于防止在开发和维护过程中发生的几种错误。
我知道很多人对私有成员变量名使用前缀或后缀。对于那些没有,但只是使用名称的人 - 如果你想拥有同名的构造函数参数,你如何初始化它们?
您只需在初始化列表中初始化它们:
struct foo
{
foo(int bar) : bar(bar) {}
private:
int bar;
};
请注意,初始化列表是在构造函数中显式初始化成员的唯一方法。一旦进入构造函数的主体,成员就已经被初始化了。
顺便说一句,C++ 允许您在声明时初始化一个成员,在这种情况下,它被初始化为该值,除非在构造函数中另外初始化:
struct foo
{
foo(int bar) : bar(bar) {}
foo() {} // bar initialized to 42
private:
int bar = 42;
};
如果使用初始化列表,只需使用相同的名称,编译器就会理解您的意思。
示例:
Book::Book(std::string title, int year)
: title(title), year(year)
{}
最简单的方法是使用内存初始化器列表。例如
class A
{
private:
int data;
public:
A( int data ) : data( data ) {}
};
如果要在构造函数体内使用数据成员,则有两种方法可以区分数据成员和参数
class A
{
private:
int data;
public:
A( int data ) : data( data )
{
A::data *= data;
this->data *= data;
}
};
通过简单地编写它们。语言规则防止出问题。
struct Foo
{
Foo(int x) : x(x) {};
int x;
};
在()
之外,只有数据成员在范围内;在内部,函数参数 隐藏了 成员,就像在普通函数体中一样:
int x = 2;
void foo(int x)
{
// any access to `x` means the argument
}
这是我在命名数据成员时不使用 m_
前缀样式(或等效样式)的众多原因之一。
方法正式名称的价值不高,考虑到它的范围是多么有限。然而,应该 仍然有动力能够立即区分这些项目 'origins' 一目了然。
这已成为我的习惯
a) 在我的数据属性名称前加上 'm_'、
和
b) 在方法/函数参数名称前加上'a_' 或'an_',始终力求语法正确。
LMBM::Node::Node(uint8_t a_max) : m_max (a_max) ...
void* LMBM::Node::threadEntry(void* an_objPtr) ...
void DV1::processDirent(const std::string& a_dirPath) ...
void DV1::handleDT_REG (DV::Dirent* an_ent,
const std::string& a_path) ...
FInfo (const std::string& aPfn, const int64_t& aFileSz) :
m_pfn (aPfn),
m_fileSz (aFileSz) ...
目标 - 更容易阅读
动机-代码一次编写,多次阅读
我理解 ctor 初始化列表的特殊情况。但我也相信使用前缀(您选择的)确实有助于防止在开发和维护过程中发生的几种错误。