我有一个Wicket页面类,它根据抽象方法的结果设置页面标题.
public abstract class BasicPage extends WebPage {
public BasicPage() {
add(new Label("title", getTitle()));
}
protected abstract String getTitle();
}
Run Code Online (Sandbox Code Playgroud)
NetBeans通过消息"构造函数中的可覆盖方法调用"警告我,但它应该有什么问题呢?我能想象的唯一选择是将其他抽象方法的结果传递给子类中的超级构造函数.但是很多参数很难读懂.
为什么以下示例打印"0"以及必须更改它以打印"1",如我所料?
#include <iostream>
struct base {
virtual const int value() const {
return 0;
}
base() {
std::cout << value() << std::endl;
}
virtual ~base() {}
};
struct derived : public base {
virtual const int value() const {
return 1;
}
};
int main(void) {
derived example;
}
Run Code Online (Sandbox Code Playgroud) 我写了一些代码:
class Base {
// Default value
myColor = 'blue';
constructor() {
console.log(this.myColor);
}
}
class Derived extends Base {
myColor = 'red';
}
// Prints "blue", expected "red"
const x = new Derived();
Run Code Online (Sandbox Code Playgroud)
我期望我的派生类字段初始化程序在基类构造函数之前运行.相反,派生类myColor在基类构造函数运行之前不会更改属性,因此我在构造函数中观察到错误的值.
这是一个错误吗?怎么了?为什么会这样?我该怎么做呢?
这是来自C++ 11标准sec 12.7.4.这相当令人困惑.
B::B未定义?不是它只是打电话a.A::f?4构造函数,包括虚函数(10.3),可以在构造或销毁期间调用(12.6.2).当从构造函数或析构函数直接或间接调用虚函数时,包括在构造或销毁类的非静态数据成员期间,以及调用所适用的对象是正在构造的对象(称为x)或者破坏,被调用的函数是构造函数或析构函数类中的最终覆盖,而不是在更多派生类中覆盖它.如果虚函数调用使用显式类成员访问(5.2.5)并且对象表达式引用x的完整对象或该对象的基类子对象之一但不是x或其基类子对象之一,则行为未定义.[例如:
Run Code Online (Sandbox Code Playgroud)struct V { virtual void f(); virtual void g(); }; struct A : virtual V { virtual void f(); }; struct B : virtual V { virtual void g(); B(V*, A*); }; struct D : A, B { virtual void f(); virtual void g(); D() : B((A*)this, this) { } }; B::B(V* v, A* a) { f(); // calls V::f, not A::f g(); // calls B::g, not D::g v->g(); // …
我的问题不是从基类构造函数调用虚拟成员函数,而是指向虚方法成员函数的指针在基类构造函数中是否有效.
鉴于以下内容
class A
{
void (A::*m_pMember)();
public:
A() :
m_pMember(&A::vmember)
{
}
virtual void vmember()
{
printf("In A::vmember()\n");
}
void test()
{
(this->*m_pMember)();
}
};
class B : public A
{
public:
virtual void vmember()
{
printf("In B::vmember()\n");
}
};
int main()
{
B b;
b.test();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
对于所有兼容的c ++编译器,这会产生"In B :: vmember()"吗?
我不明白这个:
3.8/1"类型T的对象的生命周期在以下情况下结束: - 如果T是具有非平凡析构函数(12.4)的类类型,则析构函数调用开始,或者 - 对象占用的存储器被重用或释放. "
如果生命周期在析构函数启动之前结束,那是不是意味着访问析构函数中的成员是未定义的行为?
我也看到了这句话:
12.7"对于具有非平凡析构函数的对象,在析构函数完成执行后引用该对象的任何非静态成员或基类会导致未定义的行为."
但它并不清楚析构函数中允许的内容.
abstract class Route {
abstract readonly name?: string;
protected abstract pattern: string;
public constructor() {
// Do something with `this.name` and `this.pattern`.
console.log(this.pattern); // Typecheck error
}
abstract handle(): void;
}
Run Code Online (Sandbox Code Playgroud)
这会引发错误,因为this.pattern不会在构造函数中访问。为什么我无法访问它?
当我通过Visual Studio的代码分析实用程序运行一些代码时,我收到一个警告,我不确定如何解决.也许这里的某个人遇到了类似的问题,解决了这个问题,并愿意分享他们的见解.
我正在编写DataGridView控件中使用的自定义绘制单元格.代码类似于:
public class DataGridViewMyCustomColumn : DataGridViewColumn
{
public DataGridViewMyCustomColumn() : base(new DataGridViewMyCustomCell())
{
}
Run Code Online (Sandbox Code Playgroud)
它会生成以下警告:
CA2000:Microsoft.Reliability:在方法'DataGridViewMyCustomColumn.DataGridViewMyCustomColumn()'中,在对所有引用超出范围之前,对对象'new DataGridViewMyCustomCell()'调用System.IDisposable.Dispose.
我知道它警告我DataGridViewMyCustomCell(或它继承自的类)实现了IDisposable接口,并且应该调用Dispose()方法来清理DataGridViewMyCustomCell声明的任何资源.
我在互联网上看到的示例建议使用块来限制对象的生命周期并让系统自动处理它,但是当移动到构造函数的主体中时无法识别base,因此我无法编写使用阻止它...我不确定我还想要做什么,因为不会指示运行时释放仍然可以在以后在基类中使用的对象?
我的问题是,代码是否正常?或者,如何重构以解决警告?除非确实合适,否则我不想压制警告.
可能重复:
在构造函数内调用虚函数
main.cpp中
#include <iostream>
class BaseClass {
public:
BaseClass() {
init();
}
virtual ~BaseClass() {
deinit();
}
virtual void init() {
std::cout << "BaseClass::init()\n";
}
virtual void deinit() {
std::cout << "BaseClass::deinit()\n";
}
};
class SubClass : public BaseClass {
public:
virtual void init() {
std::cout << "SubClass::init()\n";
}
virtual void deinit() {
std::cout << "SubClass::deinit()\n";
}
};
int main() {
SubClass* cls = new SubClass;
delete cls;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么init()并deinit()没有正确重写和基类的方法被调用,而不是子类的吗?使其有效的要求是什么?
BaseClass::init()
BaseClass::deinit()
Run Code Online (Sandbox Code Playgroud) 这是我的代码片段:
class Base {
public:
Base() {
foo();
bind();
}
virtual void foo() {
std::cout << "base foo\n";
}
void bind() {
fn = std::bind(&Base::foo, this);
};
std::function<void()> fn;
};
class Derived : public Base {
public:
void foo() override {
std::cout << "derived foo\n";
}
void bind() {
}
int val;
};
int main() {
Base* p = new Derived();
p->fn();
}
Run Code Online (Sandbox Code Playgroud)
输出是:
class Base {
public:
Base() {
foo();
bind();
}
virtual void foo() {
std::cout << "base …Run Code Online (Sandbox Code Playgroud) c++ ×6
constructor ×5
class ×3
inheritance ×2
oop ×2
typescript ×2
abstract ×1
c# ×1
c++11 ×1
ca2000 ×1
destructor ×1
ecmascript-6 ×1
java ×1
javascript ×1
overriding ×1
reliability ×1
stdbind ×1
virtual ×1