我收到了一些C++代码,其中包含如下定义的各种结构:
typedef struct _someStruct_ {
std::string someString;
std::vector<std::string> someVectorOfStrings;
int someOtherStuff;
~_someStruct_()
{
someString.clear();
someVectorOfStrings.clear();
}
} someStruct;
Run Code Online (Sandbox Code Playgroud)
这里的析构函数是完全冗余的 - 如果结构是由默认的析构函数破坏的,那么任何字符串,向量等都不会被破坏吗?
如果我编写了代码,我就不会想到在这里添加一个显式的析构函数 - 我只是让编译器继续使用它.
据我所知,你可能需要在结构中创建自己的析构函数的唯一时间是结构的任何成员是否包含指向可能需要清理的数据的指针,或者是否有一些额外的功能(例如用于调试,记录时)需要一个结构被删除).
我在这里遗漏了什么 - 有没有理由在析构函数中明确清除字符串和向量?我怀疑发送给我的是一个C程序员(参见typedef),他试图将一些C代码转换成C++.
我写了以下代码片段:
void foo()
{
struct _bar_
{
int a;
} bar;
cout << "Value of a is " << bar.a;
}
Run Code Online (Sandbox Code Playgroud)
并用g ++ 4.2.1(Mac)编译它.输出为"a的值为0".
是否真的说c ++中的结构的数据成员默认是初始化的(与c相比)?或者观察到的结果是巧合吗?
我可以想象c ++中的结构有一个默认的构造函数(因为结构和类在c ++中几乎相同),这可以解释为什么bar的数据成员a初始化为零.
我正在使用一个范围枚举来枚举我正在实现的某个状态机中的状态.例如,让我们说:
enum class CatState
{
sleeping,
napping,
resting
};
Run Code Online (Sandbox Code Playgroud)
在我定义状态转换表的cpp文件中,我想使用等价的东西,using namespace X这样我就不需要为我的所有州名添加前缀CatState::.换句话说,我想用sleeping而不是CatState::sleeping.我的转换表有很多列,因此避免使用CatState::前缀会使事情变得更紧凑和可读.
那么,有没有办法避免一直打字CatState::?
是的,是的,我已经意识到了陷阱using namespace.如果有强类型枚举的等价物,我保证只在我的cpp实现文件中的有限范围内使用它,而不是邪恶.
由于此环境中的GNU标准库实现,我正在努力解决c ++ 11符号解析中的模糊问题:
例:
#include <iostream>
#include <string>
struct version {
unsigned major;
unsigned minor;
unsigned patch;
version(unsigned major, unsigned minor, unsigned patch) :
major(major), minor(minor), patch(patch) { }
friend std::ostream & operator<<(std::ostream & out, version const& v) {
out << v.major << ".";
out << v.minor << ".";
out << v.patch;
return out;
}
};
int main(int argc, char ** argv) {
version v(1, 1, 0);
std::cout << v << …Run Code Online (Sandbox Code Playgroud) 在声明字符串集时,我有几个要初始化的单词.
...
using namespace std;
set<string> str;
/*str has to contain some names like "John", "Kelly", "Amanda", "Kim".*/
Run Code Online (Sandbox Code Playgroud)
我不想str.insert("Name");每次都使用.
任何帮助,将不胜感激.
我碰巧发现可以使用using指令直接在封闭类之外访问嵌套的私有模板类:
class wrapper
{
private:
template <typename T>
class __tklass {};
class __klass {};
};
template <typename T>
using tklass = wrapper::__tklass<T>; // Expected error but compiles OK
// using klass = wrapper::__klass; // "Error: __klass is private"
int main()
{
tklass<int> v1; // Expected error but compiles OK
// wrapper::__tklass<int> v3; // "Error: __tklass is private"
// wrapper::__klass v4; // "Error: __klass is private"
}
Run Code Online (Sandbox Code Playgroud)
标记为"错误:__ xxxx为私有"的行在取消注释时正确报告错误.但是tklass编译的行没有编译器的任何抱怨.
那么,为什么编译器标记tklass为错误,尽管wrapper::__tklass它是私有的?是否有标准允许的任何机会?如果是这样,那不会被认为是严重的访问违规行为吗?
我试过gcc-4.9.2,clang-3.5.0和visual studio 2013 …
是否可以转发声明一个嵌套类,然后将其用作外部类的具体(不是指向/引用)数据成员的类型?
IE
class Outer;
class Outer::MaybeThisWay // Error: Outer is undefined
{
};
class Outer
{
MaybeThisWay x;
class MaybeThatOtherWay;
MaybeThatOtherWay y; // Error: MaybeThatOtherWay is undefined
};
Run Code Online (Sandbox Code Playgroud) 在我看来,当有人放入一个恰好与根级命名空间同名的新命名空间并且神秘地改变了许多程序的含义时,使用未锚定的命名空间只会引发麻烦.那么,为什么人们总是说std::而不是::std::.他们真的应该说"我想用任何std方便的东西,而不是根本的东西."?
这是我的意思的一个例子:
在fred/Foo.h中:
#include <string>
namespace fred {
class Foo {
public:
void aPublicMember(const std::string &s);
};
} // end namespace fred
Run Code Online (Sandbox Code Playgroud)
在fred/Bar.h中:
namespace fred {
namespace std { // A standard fred component
class string { // Something rather unlike the ::std::string
// ...
};
} // namespace std
class Bar {
public:
void aPublicMember(std::string &s);
};
} // namespace fred
Run Code Online (Sandbox Code Playgroud)
在oops.cpp中:
#include <string>
#include "fred/Bar.h"
#include "fred/Foo.h" // Oops, the meaning of …Run Code Online (Sandbox Code Playgroud) class C {
private:
int member_; // here is the underscore I refer to.
}
Run Code Online (Sandbox Code Playgroud)
Google样式指南和Geosoft的C++样式指南推荐使用此下划线.
我知道有不同的意见和口味.
我想问一下使用它或者被迫使用它的人是否认为它们对它们有益,中性或有害.为什么?
这是我的答案:
我理解它背后的动机,但它并不能说服我.我尝试了它,我得到的只是整个类的一点点混乱,但构造函数中的成员初始化更简单.我没有遇到下划线帮助私有成员变量和其他变量之间有所不同的情况(除了提到的初始化).
在这方面,我认为这种风格有害.
首先,我知道这个问题之前已被问过几次,最后,这主要是个人偏好的问题,但阅读有关该主题的所有主题,有些事情对我来说并不清楚.
基本上,大多数人都同意的一点是,公共成员应该是PascalCased而私人成员应该是低级的.CamelCased.
通常引发争论的问题是是否用私人成员或其他任何东西作为私人成员的前缀.前缀违反了几个StyleCop规则(显然可以关闭)
不加前缀的基本原理是你应该使用它.改为加前缀.
我遇到的问题是我不明白它是如何产生影响的?我的意思是,并不是说你不能在课堂上的公共成员上使用它.
让我们想象一下Customer类,看起来像这样:
class Customer
{
private int age;
public int Age
{
get { return this.age; }
set { this.age = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
(显然,在这么简单的情况下,我可以使用autoproperty,但这只是一个例子).
如果我在这个类中添加了第二个属性,没有什么能阻止我使用this.Age(公共属性)而不是this.age(私有字段)来引用它.有时候,如果在getter级别应用了一些验证或格式化,它甚至可以被发现.
此外,如果我的类的其他一些属性需要修改客户的Age,那么直接使用属性而不是后备字段是有意义的,因为setter也可以实现一些业务规则验证,对吧?
换句话说,我真的不知道this关键字如何避免私有支持成员和公共属性之间的混淆,因为这可以在两者上使用并且IntelliSense显示两者?
谢谢.
c++ ×9
c++11 ×3
c# ×1
coding-style ×1
destructor ×1
enums ×1
linux ×1
namespaces ×1
nested-class ×1
set ×1
string ×1
struct ×1
templates ×1
using ×1