关于const方法有一条规则。如果该方法是const,并且我们试图在同一方法中使用另一个函数,那么它也应该是const。否则,我们将出现编译错误。我试图在math.h库中找到abs()函数的声明,这是我发现的内容:Declarations of abs() 这意味着abs()函数不是const,但是当我在const方法中使用它时,我没有编译错误。有人可以解释为什么吗?
class D:public B,C
{
public:
D()
{
cout<<"This is constuctor D"<<endl;
}
int fun3() const;
~D()
{
cout<< "Destructor D"<<endl;
}
};
int D::fun3() const
{
int x=-3;
return abs(x);
}
答案 0 :(得分:3)
这里对const
成员函数的约束存在误解。
const
成员函数可以调用所需的任何函数,只要它不更改对象的状态即可。因此fun3()
的编译效果很好,因为它不会更改任何成员变量,并且不会为同一对象调用任何非常量成员函数。
重要说明: public B,C
可能与您的想法无关:这意味着D公开地继承自B,而私有地继承自C。从C公开继承,您必须声明public B, public C
。
答案 1 :(得分:3)
首先,请取消了解您认为的知识。让我们看看成为const
成员意味着什么。
class D {
public:
int fun2();
int fun3() const;
};
这说明了什么?有一个名为D
的类。有两个成员函数fun2
和fun3
,每个成员函数都带有一个隐藏的this
参数,而没有其他参数。
等等!隐藏参数?嗯,是。您可以在函数内使用this
;它的价值必须来自某个地方。所有非静态成员函数均具有此隐藏参数。但是,并非所有非静态成员函数都具有相同类型的隐藏参数。如果要显示隐藏参数,则声明将如下所示:
int D::fun2(D * this);
int D::fun3(const D * this);
注意const
在此伪声明中如何存在?这就是声明const
成员函数的效果:this
指向const
对象,而不是非const
对象。
现在回到问题。 fun3
可以呼叫fun2
吗?好吧,fun3
会将其this
指针(指向常量对象的指针)传递给fun2
,后者需要一个指向对象的指针。那将意味着失去稳定性,所以这是不允许的。
fun3
可以打电话给abs
吗?好吧,fun3
会将一个整数传递给abs
。没问题问题是失去了this
的稳定性。只要避免这种情况,就可以了。
答案 2 :(得分:0)
const
应用于方法仅表示this
指针,即指向该方法在其上运行的实例的指针,是const
。这意味着它不能修改字段,只能在其上调用const
方法 ,而不是通常的方法。
完全可以接受调用自由函数,甚至可以在同一类的不同对象上调用非const
方法,只要该对象不是{{1} }。
答案 3 :(得分:0)
考虑这个
using Android.Graphics.Drawables;
using Android.OS;
using Android.Support.V4.App;
using Android.Views;
using Android.Webkit;
using Android.Widget;
namespace BottomNavigationViewPager.Fragments
{
public class TheFragment1 : Fragment
{
string _title;
string _icon;
protected static WebView _wv;
public static TheFragment1 NewInstance(string title, string icon) {
var fragment = new TheFragment1();
fragment.Arguments = new Bundle();
fragment.Arguments.PutString("title", title);
fragment.Arguments.PutString("icon", icon);
return fragment;
}
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
if (Arguments != null)
{
if(Arguments.ContainsKey("title"))
_title = (string)Arguments.Get("title");
if (Arguments.ContainsKey("icon"))
_icon = (string)Arguments.Get("icon");
}
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = inflater.Inflate(Resource.Layout.TheFragmentLayout1, container, false);
_wv = view.FindViewById<WebView>(Resource.Id.webView1);
var _wvc = new MyWebViewClient();
_wv.SetWebViewClient(_wvc);
//string _wtf = "header";
_wv.Settings.JavaScriptEnabled = true;
_wv.Settings.AllowFileAccess = true;
_wv.Settings.AllowContentAccess = true;
//_wvc.OnPageFinished(_wv, _jsHideBannerC);
_wv.LoadUrl("https://www.duckduckgo.com/");
return view;
}
private class MyWebViewClient : WebViewClient
{
public override void OnPageStarted(WebView view, string url, Android.Graphics.Bitmap favicon)
{
base.OnPageStarted(view, url, favicon);
}
public override void OnPageFinished(WebView view, string url)
{
base.OnPageFinished(view, url);
string _jsHideBanner = "javascript:(function() { " +
"document.getElementById('content_homepage').style.display='none'; " + "})()";
string _jsHideBannerC = "javascript:(function() { " +
"document.getElementsByClassName('logo-wrap--home').style.display='none'; " + "})()";
_wv.LoadUrl(_jsHideBanner);
}
}
}
}
每当您在#include <iostream>
int f(int num) { return num+1; }
int fr(int& num) { return num+1; }
int fcr(const int& num) { return num+1; }
class D
{
public:
int value= 0;
public:
void f1() { value++; }
int f2() const { return value; }
int f3() { return value; }
static void f4() { std::cout << "Hello" << std::endl; }
void f5() const;
};
void D::f5() const
{
// Prohibited:
// f1(); // modifies this
// f3(); // might modify this
// value++; // modifies this->value, thus modifies this
// value= 2; // modifies this->value, thus modifies this
// value= abs(value); // modifies this->value, thus modifies this
// fr(value); // takes value by reference and might modify it
//
// Permitted:
f2(); // const function, does not modify this
std::cout << value << std::endl; // independent function, does not modify this; read access to this->value is const
std::cout << abs(value) << std::endl; // independent function, does not modify this; read access to this->value is const
f4(); // static function, does not modify this
f(value); // function, does not modify this; takes value as read only (makes copy)
fcr(value); // function, does not modify this; takes value as read only by reference
D otherObject;
otherObject.f1(); // modifies otherObject (non const), does not modify this
}
int main()
{
const D d;
d.f5();
}
内调用诸如f4()
之类的成员函数时,都会传递与f5()
等效的隐式this
指针。在this->f4()
内部,f5()
的类型不是const
,而是D*
。因此,您无法进行const D*
(相当于value++
的{{1}}。但是您可以呼叫this->value++
,const D*
或任何不需要{{ 1}},然后尝试对其进行修改。)
如果abs
的类型为printf
,则选择this
时,其类型为this->value
,您可以自由对其进行修改。如果对this
执行相同的操作,其类型将变为D*
,则无法对其进行修改,但可以将其复制并作为const引用进行访问以供读取。