是否可以使用子类的构造函数的初始化列表来初始化在父类中声明为protected的数据成员?我无法让它发挥作用.我可以解决它,但如果我不必这样做会很好.
一些示例代码:
class Parent
{
protected:
std::string something;
};
class Child : public Parent
{
private:
Child() : something("Hello, World!")
{
}
};
Run Code Online (Sandbox Code Playgroud)
当我尝试这个时,编译器告诉我:"类'Child'没有任何名为'something'的字段".这样的事情可能吗?如果是这样,语法是什么?
非常感谢!
在内部和关于生成的代码,是否有真正的区别:
MyClass::MyClass(): _capacity(15), _data(NULL), _len(0)
{
}
Run Code Online (Sandbox Code Playgroud)
和
MyClass::MyClass()
{
_capacity=15;
_data=NULL;
_len=0
}
Run Code Online (Sandbox Code Playgroud)
谢谢...
冒号运算符(":")在这个构造函数中做了什么?它等同于MyClass(m_classID = -1, m_userdata = 0);
?
class MyClass {
public:
MyClass() : m_classID(-1), m_userdata(0) {
}
int m_classID;
void *m_userdata;
};
Run Code Online (Sandbox Code Playgroud) 我有一个python类,看起来像这样:
class Process:
def __init__(self, PID, PPID, cmd, FDs, reachable, user):
Run Code Online (Sandbox Code Playgroud)
其次是:
self.PID=PID
self.PPID=PPID
self.cmd=cmd
...
Run Code Online (Sandbox Code Playgroud)
有没有办法自动初始化这些实例变量,比如C++的初始化列表?它会节省大量冗余代码.
在C++中,您可以使用初始化列表在构造函数开始运行之前初始化类的字段.例如:
Foo::Foo(string s, double d, int n) : name(s), weight(d), age(n) {
// Empty; already handled!
}
Run Code Online (Sandbox Code Playgroud)
我很好奇为什么Java没有类似的功能.根据Core Java:第1卷:
C++使用这种特殊语法来调用字段构造函数.在Java中,不需要它,因为对象没有子对象,只有指向其他对象的指针.
这是我的问题:
它们是什么意思"因为对象没有子对象?" 我不明白子对象是什么(我试着查找它); 它们是指扩展超类的子类的实例化吗?
至于为什么Java没有像C++这样的初始化列表,我认为原因是因为所有字段在Java中都已默认初始化,并且因为Java使用super
关键字来调用super(或C++语言中的基础) - 类构造函数.它是否正确?
我所知道的使用初始化列表的好处是它们在初始化非内置的类成员时提供了效率.例如,
Fred::Fred() : x_(whatever) { }
比较好,
Fred::Fred() { x_ = whatever; }
如果x是自定义类的对象.除此之外,为了保持一致性,这种风格甚至与内置类型一起使用.
这样做的最常见好处是提高了性能.如果表达式与成员变量x_的类型相同,则任何表达式的结果都直接在x_中构造 - 编译器不会创建该对象的单独副本.
使用另一种样式,表达式可以创建单独的临时对象,并将此临时对象传递给x_对象的赋值运算符.然后该临时对象在;处被破坏.那效率很低.
问题
使用初始化列表,以下示例中是否存在任何效率增益.我认为没有收获.第一个版本调用字符串的复制构造函数,另一个调用字符串的赋值运算符(没有创建任何临时的).这是正确的吗?
class MyClass
{
public:
MyClass(string n):name(n) { }
private:
string name;
};
class MyClass
{
public:
MyClass(string n)
{
name=n;
}
private:
string name;
};
Run Code Online (Sandbox Code Playgroud) 最近我创建了课程Square
:
=========头文件======
class Square
{
int m_row;
int m_col;
public:
Square(int row, int col): m_row(row), m_col(col)
};
Run Code Online (Sandbox Code Playgroud)
========== cpp文件======
#include "Square.h"
Square::Square(int row, int col)
{
cout << "TEST";
}
Run Code Online (Sandbox Code Playgroud)
但后来我收到很多错误.如果我删除cpp文件并将头文件更改为:
=========头文件======
class Square
{
int m_row;
int m_col;
public:
Square(int row, int col): m_row(row), m_col(col) {};
};
Run Code Online (Sandbox Code Playgroud)
它没有错误.这是否意味着初始化列表必须出现在头文件中?
好的,成员变量可用于初始化初始化列表中的其他成员变量(注意初始化顺序等).会员职能怎么样?具体来说,这个片段是否符合C++标准?
struct foo{
foo(const size_t N) : N_(N), arr_(fill_arr(N)) {
//arr_ = fill_arr(N); // or should I fall back to this one?
}
std::vector<double> fill_arr(const size_t N){
std::vector<double> arr(N);
// fill in the vector somehow
return arr;
}
size_t N_;
std::vector<double> arr_;
// other stuff
};
Run Code Online (Sandbox Code Playgroud) 最近我从cppreference中读到了一个例子.../vector/emplace_back:
struct President
{
std::string name;
std::string country;
int year;
President(std::string p_name, std::string p_country, int p_year)
: name(std::move(p_name)), country(std::move(p_country)), year(p_year)
{
std::cout << "I am being constructed.\n";
}
Run Code Online (Sandbox Code Playgroud)
我的问题:这std::move
真的需要吗?我的观点是,这p_name
不是在构造函数体中使用,所以,也许,语言中有一些规则默认使用移动语义?
将std :: move初始化列表添加到每个重要成员(例如std::string
,std::vector
)会非常烦人.想象一下用C++ 03编写的数百个KLOC项目 - 我们是否应该添加到处std::move
?
这个问题:move-constructor-and-initialization-list答案说:
作为一个黄金法则,无论何时你通过右值引用来获取内容,你需要在std :: move中使用它,并且每当你通过通用引用(即用&&推导出模板化类型)时,你需要在std ::里面使用它向前
但我不确定:通过价值而不是普遍的参考?
[UPDATE]
使我的问题更清楚.构造函数参数可以被视为XValue - 我的意思是到期值?
在这个例子AFAIK我们不使用std::move
:
std::string getName()
{
std::string local = "Hello SO!";
return local; // std::move(local) is not needed nor …
Run Code Online (Sandbox Code Playgroud) c++ language-lawyer initialization-list move-semantics c++11
我有一个类看起来像:
class Foo
{
public:
Foo();
virtual ~Foo();
private:
Odp* bar;
};
Run Code Online (Sandbox Code Playgroud)
我希望初始化bar
为NULL
.这是最好的方法吗?
Foo::Foo() : bar(NULL)
{
}
Run Code Online (Sandbox Code Playgroud)
此外,析构函数是否必须是虚拟的?(如果这是真的,那么构造函数也必须是虚拟的吗?)