假设我有一个类模板:
template <class T>
struct A
{
T value;
void foo(auto fun) {
fun(value);
// ^^^^^^^ Pass value as a const object
}
};
Run Code Online (Sandbox Code Playgroud)
我想常量添加到value,打电话时fun 这样只有接受功能 T,T const&,T const*可调用。我最初的方法是创建foo一个 const 成员函数,但是对于引用和指针成员来说这失败了,因为 const 成员函数可以修改它们(你只是不能对这些成员进行变基)。
我也尝试使用std::add_const并将std::as_const值传递给参数函数 ( fun) 但这会进行如下转换:
T = MyData* // say T is the type "Pointer to MyData"
add_const<T> = MyData *const // constness is added to the pointer,
// i.e. it becomes constant …Run Code Online (Sandbox Code Playgroud) 在RAII中,资源在访问之前不会初始化.但是,许多访问方法被声明为常量.我需要调用mutable(非const)函数来初始化数据成员.
示例:从数据库加载
struct MyClass
{
int get_value(void) const;
private:
void load_from_database(void); // Loads the data member from database.
int m_value;
};
int
MyClass ::
get_value(void) const
{
static bool value_initialized(false);
if (!value_initialized)
{
// The compiler complains about this call because
// the method is non-const and called from a const
// method.
load_from_database();
}
return m_value;
}
Run Code Online (Sandbox Code Playgroud)
我的原始解决方案是将数据成员声明为mutable.我宁愿不这样做,因为它表明其他方法可以改变成员.
如何转换load_from_database()语句以摆脱编译器错误?
我将使用以下(普通)接口作为示例:
struct IObject
{
virtual ~IObject() {}
virtual std::string GetName() const = 0;
virtual void ChangeState() = 0;
};
Run Code Online (Sandbox Code Playgroud)
逻辑规定GetName应该是const成员函数,而不ChangeState应该.
到目前为止,我见过的所有代码都没有遵循这个逻辑.也就是说,GetName在上面的例子中不会被标记为const成员函数.
这种懒惰/粗心大意还是有正当理由的?const在逻辑上要求我强制客户实现成员函数的主要缺点是什么?
编辑:感谢您的回复.我认为这几乎是一致的:懒惰/无知是我所看到的原因.
我一直在研究一些类似于以下内容的代码:
typedef struct
{
unsigned char x;
unsigned short y;
unsigned char[NUM_DEFINED_ELSEWHERE];
} My_Struct;
static My_Struct my_useful_struct; // Variables initialized elsewhere in code.
void myFunction(const My_Struct * p_my_struct)
{
/* Performs various read-only actions utilizing p_my_struct. */
}
void myOtherFunction(void)
{
static My_Struct * p_struct = &my_useful_struct;
myFunction(p_struct);
}
Run Code Online (Sandbox Code Playgroud)
我的代码编译没有任何问题,但在审查时我被告知,除非我对 p_struct 进行类型转换,否则这可能会导致在某些平台(即 8051)上出现未定义的行为。然而,我什至从未收到过有关编译器的警告。 在将指针传递给函数时不进行类型转换(const My_Struct *)是否会导致未定义的行为?
我使用指向的指针声明上述函数的原因const是因为我希望能够处理指向 const 的指针和指针。 在上述情况下不进行类型转换是一种不好的编码习惯吗?
感谢您的帮助!
我想const QList根据指针的值为a赋值.
invar是一个指针,如果它是NULL我想要分配第一个值const QList mylist,如果不是NULL,另一个值.但是观察到了正确性:我不打算在mylist之后改变价值.
是否有可能
if(invar)
const QList<Type> zoneList = invar->getZones();
else
const QList<Type> zoneList = aList ;
Run Code Online (Sandbox Code Playgroud)
我zoneList确切地定义了一次,为什么这不起作用?
另外,正如我zoneList在我的方法的下一部分中使用的那样,我得到了这个编译错误:undeclared identifier.
但我也不允许这样写
const QList<Type> zoneList ;
if(invar)
zoneList = invar->getZones();
else
zoneList = NULL ;
Run Code Online (Sandbox Code Playgroud)
我有编译器错误错误1
error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const QList<T>' (or there is no acceptable conversion)
Run Code Online (Sandbox Code Playgroud)
是否可以根据条件为此const QList分配两个不同的值?那么写它的正确方法是什么?
c++ const const-correctness variable-assignment conditional-statements
我是c ++的新手,面临着常量对象的问题.我已经声明了一个名为function的常量成员函数(并且我已经知道常量函数只能由常量对象调用)但是这里常规对象调用一个常量对象.请解释为什么会这样.代码就在这里
myClass.h
#ifndef MYCLASS_H
#define MYCLASS_H
class myClass
{
public:
void function() const;
};
#endif
Run Code Online (Sandbox Code Playgroud)
myClass.cpp
#include "myClass.h"
#include<iostream>
using namespace std;
void myClass::function() const{
cout<<"this is a constant object";
}
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include <iostream>
using namespace std;
#include "myClass.h"
int main() {
myClass obj;
obj.function();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
请帮帮我.谢谢
的典型实施的operator+=经过RHS作为const参考:
X& operator+=(const X& rhs)
Run Code Online (Sandbox Code Playgroud)
然而,在
x += x;
Run Code Online (Sandbox Code Playgroud)
RHS被修改。这会调用UB吗?
示例代码:
#include <string>
#include <set>
using namespace std;
class x
{
private:
int i;
public:
int get_i() const { return i; }
};
struct x_cmp
{
bool operator()(x const & m1, x const & m2)
#if _MSC_VER
const
#endif
{
return m1.get_i() > m2.get_i();
}
};
std::set<x, x_cmp> members;
void add_member(x const & member)
{
members.insert(member);
}
Run Code Online (Sandbox Code Playgroud)
调用:
$ g++ -c -std=c++14 -pedantic -Wall -Wextra
<nothing>
$ clang++ -c -std=c++14 -pedantic -Wall -Wextra
<nothing>
$ icc -c -std=c++14 -pedantic -Wall …Run Code Online (Sandbox Code Playgroud) 我想实现一个Model类的Observer,它不会改变Model.因此,它应该能够使用const-Reference来访问Model.但注册观察员禁止这样做.
以下是我的项目中如何实现观察者模式:
//Attributes of type Observable are used by classes that want to notify others
//of state changes. Observing Objects register themselves with AddObserver.
//The Observable Object calls NotifyObservers when necessary.
class Notifier
{
public:
AddObserver(Observer*);
RemoveObserver(Observer*);
NotifyObservers();
};
class Model
{
public:
Notifier& GetNotifier() //Is non const because it needs to return a non-const
{ //reference to allow Observers to register themselves.
return m_Notifier;
}
int QueryState() const;
void ChangeModel(int newState)
{
m_Notifier.NotifyObservers();
}
private:
Notifier m_Notifier;
};
//This …Run Code Online (Sandbox Code Playgroud) 如果以前回答过这个问题我很抱歉,我无法在任何地方找到答案.
我在保持const正确性方面遇到了麻烦.
我有以下定义.
struct C {
int x,y;
};
class A {
public:
C c;
C& getC() { return c; }
};
class B {
public:
void forwardInfo(const A& a) const {
const C& c = a.getC(); // <= compiler complains here
daoObject.updateTableX(c.x,c.y);
}
};
Run Code Online (Sandbox Code Playgroud)
编译器抱怨对象a是const,因此不能调用a.getC(),因为该方法不是const.
但是我将结果分配给const引用.现在我只是将一个对象转换为非const引用,如下所示:
const C& c = ((A&)a).getC();
Run Code Online (Sandbox Code Playgroud)
这有效,但并不优雅.没有改变常数,有没有更好的方法.我相信对于对象A,返回C不是const是合理的,因为它意味着要改变.
forwardInfo也应该是const,因为我不想改变任何东西.
我不确定为什么编译器不允许我这样做并且有更好的方法吗?
PS.我可以使用getter/setter方法,但是C类可以用作传递给数据库的数据桶.
谢谢.
修正:施法中的支架位置和不正确的施法.
c++ ×9
const ×4
c ×1
c++14 ×1
constants ×1
embedded ×1
interface ×1
reference ×1
stdset ×1
templates ×1
this-pointer ×1
type-traits ×1
visual-c++ ×1