试图更好地掌握有关const重载的规则。请考虑以下代码 -
MyClass.h
class MyClass
{
public:
MyClass();
~MyClass();
};
MyClass.cpp
#include "MyClass.h"
MyClass::MyClass()
{
}
MyClass::~MyClass()
{
}
的main.cpp
#include <iostream>
#include "MyClass.h"
#include <memory>
using namespace std;
/*
void test_function(MyClass& test)
{
cout << "ref to non const" << endl;
}
*/
void test_function(const MyClass& test)
{
cout << "ref to const" << endl;
}
/*
void test_shared_ptr( shared_ptr<MyClass>& test)
{
cout << "ref to non const shared ptr to non const" << endl;
}
void test_shared_ptr ( const shared_ptr<MyClass>& test)
{
cout << "ref to const shared ptr to non const" << endl;
}
*/
void test_shared_ptr (const shared_ptr<const MyClass>& test)
{
cout << "ref to const shared ptr to const" << endl;
}
int main()
{
MyClass non_const_my_class;
test_function(non_const_my_class);
const MyClass const_my_class;
test_function(const_my_class);
shared_ptr<MyClass> non_const_ptr_to_non_const = make_shared<MyClass> (MyClass());
test_shared_ptr(non_const_ptr_to_non_const);
const shared_ptr<MyClass> const_ptr_to_non_const = make_shared<MyClass>(MyClass());
test_shared_ptr(const_ptr_to_non_const);
const shared_ptr< const MyClass> const_ptr_to_const = make_shared< const MyClass>(MyClass());
test_shared_ptr(const_ptr_to_const);
int pause;
cin >> pause;
return 0;
}
通过注释掉的方法,输出为:
ref to const
ref to const
ref to const shared ptr to const
ref to const shared ptr to const
ref to const shared ptr to const
这个输出是我所期望的,但是我遇到了一些围绕这种类型的const重载的代码的潜在错误。真的只是想对以下陈述进行一些验证:
作为最后一个问题 -
在什么情况下您可能需要以下代码?在我上面的测试代码中,将非const数据作为const引用传递给函数是完全没问题的,那么为什么我需要这样做const_cast
?
void test_const_cast(const MyClass & test)
{
//Do something
}
void test_const_cast( MyClass & test)
{
test_const_cast(const_cast<MyClass const &>(test));
}
答案 0 :(得分:0)
声明1:关闭对于C ++ 98,比C ++ 11更接近。在C ++ 11中,当涉及标准库时,添加了一个要求,即const成员函数不引入Data Races。见http://channel9.msdn.com/posts/C-and-Beyond-2012-Herb-Sutter-You-dont-know-blank-and-blank。如果一个类型的实例具有引入数据竞争的const成员函数,而非const重载没有,则将一个可变的左值传递给一个引用const的函数是不对的。 即使该函数确实违反了其参数的常量(使用List<AuthorityRole> list = new ArrayList<AuthorityRole>();
list.add(AuthorityRole.ROLE_ADMIN);
list.add(AuthorityRole.ROLE_USER);
user.setAuthorityRoles(list);
)。
声明2: 可以传递const数据作为对非const的引用,提供该函数实际上不会更改其参数引用的对象。这是const_cast<>()
的主要用例。
奖金问题:使用const_cast<>()
添加 const的代码主要在重载函数的返回值不为空时有用。例如,标准库为const_cast<>()
提供非成员begin()
和end()
函数,使得std::vector<T /* technically more type paraeters here */>
的重载,例如返回const vector<int>&
,但是需要vector<int>::const_iterator
返回vector<int>&
的重载。如果您想要vector<int>::iterator
而不仅仅是const_iterator
,并且不希望将iterator
转换为iterator
,则可能会这样做。这就是为什么C ++ 17引入const_iterator
http://en.cppreference.com/w/cpp/utility/as_const,以便更容易,而不使用可怕的as_const()
。
答案 1 :(得分:0)
将非const数据作为const的引用传递给函数总是可以的,只要该函数不会试图违反其参数的常量。这会导致编译错误。
并非总是如此。 C ++不喜欢传递用常量模板化的类型。请考虑以下代码:
#include <vector>
using std::vector;
void test(const vector<const int> & b) { }
int main() {
vector<int> a;
test(a);
}
此处,a
是int
的向量,test
接受const
的{{1}}向量。对const int
的约束本质上是一种承诺,它既不会修改test
也不会修改其中的元素;直觉上,它根本不应对b
施加任何限制。然而代码将无法编译。例如,在clang中,您会收到此错误:
a
删除test_template.cxx:11:3: error: no matching function for call to 'test'
test(a);
^~~~
test_template.cxx:5:6: note: candidate function not viable: no known conversion
from 'vector<int>' to 'const vector<const int>' for 1st argument
void test(const vector<const int> & a) { }
^
前面的const
,实际上它确实编译(至少在clang上)。因此,vector
与您总结的方式不同。
答案 2 :(得分:0)
这个问题的答案似乎是它依赖于编译器。可以将非const指针传递给const数据到一个函数,该函数将const数据的const指针作为参数与visual studio编译器一起使用,但不能与gcc一起使用。