“const”如何表示? C 和 C++ 有何不同?

发布于 2024-10-08 13:28:46 字数 386 浏览 3 评论 0原文

C 和 C++ 中变量的 const 限定有何不同?

来自: “const”仅意味着读-仅或更多?

“引发此问题的是以下答案:https://stackoverflow.com/questions/4024318# 4024417 他说 const “just” 在 C 中意味着只读。我认为这就是 const 的全部含义,无论是 C 还是 C++,他是什么意思?”

How does the const qualification on variables differ in C and C++?

from: Does "const" just mean read-only or something more?

"What prompted this question was this answer: https://stackoverflow.com/questions/4024318#4024417 where he states const "just" means read-only in C. I thought that's all const meant, regardless of whether it was C or C++. What does he mean?"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

幸福不弃 2024-10-15 13:28:46

C 中的 const 不能用于构建常量表达式。

例如:

#include <stdio.h>
int main()
{
   int i = 2;
   const int C = 2;
   switch(i)
   {
      case C  : printf("Hello") ;
      break;

      default : printf("World");
   }
}

在 C 中不起作用,因为 case 标签不会简化为整数常量。

const in C cannot be used to build constant expressions.

For example :

#include <stdio.h>
int main()
{
   int i = 2;
   const int C = 2;
   switch(i)
   {
      case C  : printf("Hello") ;
      break;

      default : printf("World");
   }
}

doesn't work in C because case label does not reduce to an integer constant.

东走西顾 2024-10-15 13:28:46

const 表示承诺不会改变变量。仍然可以改变。

class A {
  public:
    A(const int& a);
    int getValue() const;
    void setValue(int b);
  private:
    const int& a;
};
A::A(a) : a(a) {}
int A::getValue() const {
    return a;
}
void A::setValue(int b) {
    a = b;  // error
}

int main() {
    int my_a = 0;
    A a(my_a);
    std::cout << a.getValue() << std::endl;  // prints 0
    my_a = 42;
    std::cout << a.getValue() << std::endl;  // prints 42
}

没有方法 A::* 可以更改 a,但 main 可以。 C 和 C++ 之间有很多相同之处。


C++ 确实有一些(有限的)绕过 const 的方法,这些方法应该阻止程序员不恰当地丢弃 const

上这样的课。

class A {
  public:
    A();
    int getValue();
  private:
    static int expensiveComputation();
    int cachedComputation;
};

A::A() : cachedComputation(0) {}

A::getValue() {
    if (cachedComputation == 0)
        cachedComputation = expensiveComputation();
    return cachedComputation;
}

cachedComputation 隐式表示 this->cachedComputation。请记住这一点。

int main() {
    A a1;
    const A a2;
    std::cout << a1.getValue() << std::endl;
    std::cout << a2.getValue() << std::endl;  // error
}

a2.getValue() 是非法的,因为在 const A a2 上调用非 const 方法。一个可以抛弃 const-ness…

    std::cout << ((A&)a2).getValue() << std::endl;            // C-style cast
    std::cout << const_cast<A&>(a2).getValue() << std::endl;  // C++-style cast

第二种是首选,因为编译器将检查是否仅转换 const-ness,而不是其他。然而,这仍然不理想。相反,应该向类中添加一个新方法。

class A {
  public:
    int getValue() const;
};

A::getValue() const {
    if (cachedComputation == 0)
        cachedComputation = expensiveComputation();  // error
    return cachedComputation;
}

现在有一个 const 方法,所以 a2.getValue() 就可以了。但是,尾随的 const 意味着该方法被赋予一个 const A *this 指针,而不是像通常那样的 A *this 指针,使得 < code>this->cachedComputation 一个无法改变的 const int &

const_cast 可以在方法内部应用,但更好的方法是更改​​该成员的声明。

class A {
  private:
    mutable int cachedComputation;
};

现在,即使使用 const A *this,this->cachedComputation 也可以在不进行转换的情况下进行变异。

const means that you promise not to mutate the variable. It could still be changed.

class A {
  public:
    A(const int& a);
    int getValue() const;
    void setValue(int b);
  private:
    const int& a;
};
A::A(a) : a(a) {}
int A::getValue() const {
    return a;
}
void A::setValue(int b) {
    a = b;  // error
}

int main() {
    int my_a = 0;
    A a(my_a);
    std::cout << a.getValue() << std::endl;  // prints 0
    my_a = 42;
    std::cout << a.getValue() << std::endl;  // prints 42
}

No method A::* may change a, but main can. That much is identical between C and C++.


What C++ does have are a couple (limited) ways to bypass const, which are supposed to discourage programmers from discarding const inappropriately.

Take a class like this.

class A {
  public:
    A();
    int getValue();
  private:
    static int expensiveComputation();
    int cachedComputation;
};

A::A() : cachedComputation(0) {}

A::getValue() {
    if (cachedComputation == 0)
        cachedComputation = expensiveComputation();
    return cachedComputation;
}

cachedComputation implicitly means this->cachedComputation. Keep this in mind.

int main() {
    A a1;
    const A a2;
    std::cout << a1.getValue() << std::endl;
    std::cout << a2.getValue() << std::endl;  // error
}

a2.getValue() is illegal, because a non-const method is being called on a const A a2. One could cast away the const-ness…

    std::cout << ((A&)a2).getValue() << std::endl;            // C-style cast
    std::cout << const_cast<A&>(a2).getValue() << std::endl;  // C++-style cast

The second is preferred, because the compiler will check that only the const-ness is being casted, nothing else. However, this is still not ideal. Instead, there should be a new method added to the class.

class A {
  public:
    int getValue() const;
};

A::getValue() const {
    if (cachedComputation == 0)
        cachedComputation = expensiveComputation();  // error
    return cachedComputation;
}

Now there is a const method, so a2.getValue() is fine. However, the trailing const means that the method is given a const A *this pointer, not an A *this pointer like usual, making this->cachedComputation a const int & that cannot be mutated.

const_cast could be applied inside the method, but better would be to change this one member's declaration.

class A {
  private:
    mutable int cachedComputation;
};

Now, even with a const A *this, this->cachedComputation can be mutated without casting.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文