标准C库函数strtof并strtod具有以下签名:
float strtof(const char *str, char **endptr);
double strtod(const char *str, char **endptr);
Run Code Online (Sandbox Code Playgroud)
它们将输入字符串分解str为三部分:
如果endptr不是NULL,则*endptr设置为指向紧跟在转换的一部分的最后一个字符之后的字符的指针(换句话说,尾随序列的开始).
我想知道:endptr那么,为什么指向非const char指针?不是*endptr指向const char字符串的指针(输入字符串str)?
我有一个具有私有属性向量rectVec的类;
class A {
private:
vector<Rect> rectVec;
};
Run Code Online (Sandbox Code Playgroud)
我的问题是如何返回我的Vector的"只读"副本?我在想这样做:
class A {
public:
const vect<Rect>& getRectVec() { return rectVect; }
}
Run Code Online (Sandbox Code Playgroud)
这是正确的方法吗?我在想这可以防止被调用者修改向量(在向量中添加/删除Rect),向量内的Rect怎么样?
我有一个看起来像这样的遗留函数:
int Random() const
{
return var_ ? 4 : 0;
}
Run Code Online (Sandbox Code Playgroud)
我需要在遗留代码中调用一个函数,以便它现在看起来像这样:
int Random() const
{
return var_ ? newCall(4) : 0;
}
Run Code Online (Sandbox Code Playgroud)
问题是我收到了这个错误:
In member function 'virtual int Random() const':
class.cc:145: error: passing 'const int' as 'this' argument of 'int newCall(int)' discards qualifiers
Run Code Online (Sandbox Code Playgroud)
现在我知道为了解决这个错误我可以使我newCall()的const函数.但后来我有几个newCall()函数调用,所以现在我必须使所有这些函数调用const.等等,直到最后我觉得我的程序的一半将是const.
我的问题:有没有办法在Random()中调用一个不是const的函数?或者有没有任何想法如何实现newCall()内部Random()而不使我的程序const的一半.
谢谢
-josh
我知道const在C++ 中使用一个方法意味着一个对象通过该方法是只读的,但它可能仍然会改变.
但是,此代码显然通过const引用(即通过const方法)更改对象.
这段代码在C++中是否合法?
如果是这样:它是否打破const了类型系统的性质?为什么/为什么不呢?
如果没有:为什么不呢?
#include <iostream>
using namespace std;
struct DoBadThings { int *p; void oops() const { ++*p; } };
struct BreakConst
{
int n;
DoBadThings bad;
BreakConst() { n = 0; bad.p = &n; }
void oops() const { bad.oops(); } // can't change itself... or can it?
};
int main()
{
const BreakConst bc;
cout << bc.n << endl; // 0
bc.oops(); // O:) …Run Code Online (Sandbox Code Playgroud) 在C++中,可以声明堆栈分配的对象const:
const Class object;
Run Code Online (Sandbox Code Playgroud)
之后尝试在这样的对象上调用非const方法是未定义的行为:
const_cast<Class*>( &object )->NonConstMethod(); //UB
Run Code Online (Sandbox Code Playgroud)
堆分配的对象可以const具有相同的后果吗?我的意思是有可能是以下几点:
const Class* object = new Class();
const_cast<Class*>( object )->NonConstMethod(); // can this be UB?
Run Code Online (Sandbox Code Playgroud)
还是未定义的行为?
我不知道错误来自哪里.好像我将有效数据传递给[]运算符.
template <class VertexType>
typename map< Vertex<VertexType>, int >::iterator Graph<VertexType>::findEdge( const VertexType& v, const VertexType& w ) const
{
map<Vertex<VertexType>, int>::const_iterator iter = vertices[v].second.adjList.find(w);
return iter;
} // end findEdge
Run Code Online (Sandbox Code Playgroud)
错误:
error C2678: binary '[' : no operator found which takes a left-hand operand of type 'const std::map<_Kty,_Ty>' (or there is no acceptable conversion)
1> with
1> [
1> _Kty=unsigned int,
1> _Ty=Vertex<unsigned int>
1> ]
1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\map(164): could be 'Vertex<VertexType> &std::map<_Kty,_Ty>::operator [](unsigned int &&)' …Run Code Online (Sandbox Code Playgroud) 我正在试验新的尾随返回类型,我遇到了这个(简化的)代码的问题
#include <list>
class MyContainer{
std::list<int> ints;
auto begin( ) -> decltype(ints.begin())
{
return ints.begin();
}
auto begin( ) const -> decltype(ints.begin())
{
return ints.begin();
}
};
Run Code Online (Sandbox Code Playgroud)
忽略这段代码毫无意义的事实.重要的部分是使用GCC 4.6.1(带-std=c++0x标志)时生成的编译器错误:
In member function 'std::list<int>::iterator MyContainer::begin() const':
error: could not convert '((const MyContainer*)this)->MyContainer::ints.std::list<_Tp, _Alloc>::begin [with _Tp = int, _Alloc = std::allocator<int>, std::list<_Tp, _Alloc>::const_iterator = std::_List_const_iterator<int>]()' from 'std::list<int>::const_iterator {aka std::_List_const_iterator<int>}' to 'std::list<int>::iterator {aka std::_List_iterator<int>}'
Run Code Online (Sandbox Code Playgroud)
如果你是涉及模板错误的风扇不中,短篇小说的是,在的身体const的版本MyContainer::begin,则表达式ints.begin()返回类型的值std::list<int>::const_iterator(因为ints是const在这样的情况下).但是,decltype(ints.begin())生成类型std::list<int>::iterator,即在决定表达式的类型时 …
有人提出一个论点,说在现代C中,我们应该总是通过数组指针将数组传递给函数,因为数组指针具有强类型.例:
void func (size_t n, int (*arr)[n]);
...
int array [3];
func(3, &array);
Run Code Online (Sandbox Code Playgroud)
这听起来像防止各种类型相关和数组越界错误可能是一个好主意.但后来我发现我不知道如何将const正确性应用于此.
如果我这样做void func (size_t n, const int (*arr)[n])那么它是正确的.但是由于指针类型不兼容,我无法再传递数组.int (*)[3]对比const int (*)[3].限定符属于指向的数据,而不属于指针本身.
调用者中的显式强制转换将破坏增加类型安全性的整个想法.
如何将const正确性应用于作为参数传递的数组指针?它可能吗?
编辑
就像信息一样,有人说通过像这样的指针传递数组的想法可能源于MISRA C++:2008 5-2-12.例如,请参阅PRQA的高完整性C++标准.
考虑以下:
class A {
public:
const int c; // must not be modified!
A(int _c)
: c(_c)
{
// Nothing here
}
A(const A& copy)
: c(copy.c)
{
// Nothing here
}
};
int main(int argc, char *argv[])
{
A foo(1337);
vector<A> vec;
vec.push_back(foo); // <-- compile error!
return 0;
}
Run Code Online (Sandbox Code Playgroud)
显然,复制构造函数是不够的.我错过了什么?
编辑:Ofc.我无法在operator =()方法中更改this-> c,因此我没有看到如何使用operator =()(尽管std :: vector需要).