问题描述
class TestClass{public: TestClass() = default; ~TestClass() = default;public: int func(int j = i) {cout << i << endl; }private: int i = 1;};
比如这样 这样会报错 为什么?
问题解答
回答1:原答案部分有误,重新回答一下。
静态变量可以作为默认实参,不需要一定是常量。实例如下:
#include <iostream>class A {public: explicit A(int mm = n) : m(mm) {} int get() const { return m; } int foo(int i = n) const { return i; } static void set(int nn) { n = nn; }private: int m; static int n;};int A::n = 1;int main() { A a1; A a2(2); std::cout << 'a1: foo() ' << a1.foo() << ' get() ' << a1.get() << std::endl; std::cout << 'a2: foo() ' << a2.foo() << ' get() ' << a2.get() << std::endl; A::set(3); //a1.set(3); //a2.set(3); std::cout << 'A::set(3)' << std::endl; std::cout << 'a1: foo() ' << a1.foo() << ' get() ' << a1.get() << std::endl; std::cout << 'a2: foo() ' << a2.foo() << ' get() ' << a2.get() << std::endl; A a3; std::cout << 'a3: foo() ' << a3.foo() << ' get() ' << a3.get() << std::endl;return 0;}
原答案
静态常量可以,如以下两种定义都可以。
static const int i;static constexpr int i;
当然,静态常量的初始化是另一回事了。
具体例子参见《C++ Primer》第五版,7.6节,与静态成员的使用相关的部分。
回答2:这个在C++里面是不行的,虽然C++规定了参数的压栈顺序,但是标准上没有规定参数的初始化顺序,我觉得这是最大的原因,这样子 你也不能这么做
int func(int m, int n = m); // 这中写法不行,包括上面你例子中的j = this->i,//个人觉得还有一个原因就是this或者m是最后压栈的,//n = m或者j = this->i 并不能访问到m或者thisint func(int m = n, int n = 10); //虽然说理论上n是比m会早一步压人栈中,//但是因为没有规定初始化顺序所以这种写法不对
而且这种写法 编译期生成代码的时候估计会很麻烦,默认参数可以使用静态的或者字面值有些其它语言是支持这种使用非静态成员写法的
贴一段标准
ISO C++ section 8.3.6/9a nonstatic member shall not be used in a default argument expression, even if it is not evaluated, unless it appears as the id-expression of a class member access expression (5.2.5) or unless it is used to form a pointer to member (5.3.1).
ISO C++ section 8.3.6/9Default arguments are evaluated each time the function is called. The order of evaluation of function arguments is unspecified. Consequently, parameters of a functionshall not be used in default argument expressions, even if they are not evaluated.
当然也有不错的解决方案,使用重载
int func(int j);int func(){ func(this->i);}
参考
http://stackoverflow.com/questions/4539406/nonstatic-member-as-a-default-argument-of-a-nonstatic-member-function回答3:
因为在func(int j = i)时,this是第零个参数,第一个参数看不见this,自然没有办法取到this->i,就好比:
class A {public: int a = 1;};class B {public: int func(A* a, int j = a->i) { //do something }};int main(){ A a; B b; b.func(&a);}
这里func的第二个参数没法用到第一个参数里的a。
回答4:class TestClass{public: TestClass() = default; ~TestClass() = default;public: int func(int j = i) {cout << i << endl; }private: int i = 1; //这里};
成员变量可以是成员函数的默认实参,你的出错的问题不在这里,是你的成员变量初始化有问题。在成员变量的定义的进行初始化,这种写法不对。
你private下面只能定义成员变量,或者初始化静态变量。普通成员变量的初始化是在构造函数里完成的。
class TestClass{public: TestClass():i(1){};public: int func(int j = i) {cout << i << endl; }private: int i;};