The given code for my program is:
class Hive
{
private:
Bee* queen;
Bee* worker;
Bee* drone;
public:
Hive();
void activity();
~Hive();
};
Coding instructions have been provided and I must add the code. My constructor as coded, has the following error:"Cannot allocate an object of abstract type"
Hive::Hive() //This is where my error is
{
//Create an instance of each derived class
queen = new Queen(1,1) ;
worker = new Worker(1,1) ;
drone = new Drone(1,1) ;
}
void Hive::activity()
{
//Polymorphically call each classes work function
queen->Work() ;
worker->Work() ;
drone->Work() ;
}
Hive::~Hive()
{
//Deal with dynamic memory
delete queen ;
delete worker ;
delete drone ;
}
My derived class definitions are:
class Drone : Bee /*Indicate that a Drone IS A Bee*/
{
private:
char fertile;
public:
Drone(int lifespan, char fertile);
virtual void work();
};
class Queen : Bee /*indicate that a Queen IS A Bee*/
{
private:
int numBabies;
public:
Queen(int lifespan, int numBabies);
virtual void work();
};
class Worker : Bee /*Indicate that a Worker IS A Bee*/
{
private:
int honeyMade;
public:
Worker(int lifespan, int honeyMade);
virtual void work();
};
Hopefully I didn't make additional mistakes.
The main:
include <iostream>
include "Hive.h"
using namespace std;
using namespace HiveSpace;
int main()
{
Hive h;
h.activity();
return 0;
}
Classes
#ifndef HIVE_H
#define HIVE_H
#include "Bee.h"
#include "Queen.h"
#include "Drone.h"
#include "Worker.h"
namespace HiveSpace
{
class Hive
{
private:
Bee* queen;
Bee* worker;
Bee* drone;
public:
Hive();
void activity();
~Hive();
};
}
#endif
///
#include "Hive.h"
#include <iostream>
using namespace std;
namespace HiveSpace
{
Hive::Hive()
{
//Create an instance of each derived class
queen = new Queen(1,1) ;
worker = new Worker(1,1) ;
drone = new Drone(1,1) ;
}
void Hive::activity()
{
//Polymorphically call each classes work function
queen->Work() ;
worker->Work() ;
drone->Work() ;
}
Hive::~Hive()
{
//Deal with dynamic memory
delete queen ;
delete worker ;
delete drone ;
}
}
///
#ifndef BEE_H
#define BEE_H
namespace HiveSpace
{
class Bee
{
private:
int lifespan;
public:
Bee(int lifespan);
//Add pure virtual function for work
virtual void Work() = 0 ;
//Create polymorphic destructor
virtual ~Bee() ; // ADDED
};
}
#endif
/////
#include "Bee.h"
#include <iostream>
using namespace std;
namespace HiveSpace
{
void Bee::Work()
{
//Nothing to do here
}
Bee::Bee(int lifespan)
{
cout << "Constructor for Bee base class " << endl;
this->lifespan = lifespan;
}
Bee::~Bee()
{
//Nothing special to do here
cout << "Destructor for Bee base class << endl;
}
}
///
#ifndef DRONE_H
#define DRONE_H
#include "Bee.h"
namespace HiveSpace
{
class Drone : Bee /*Indicate that a Drone IS A Bee*/
{
private:
char fertile;
public:
Drone(int lifespan, char fertile);
virtual void work();
};
}
#endif
///
#include "Drone.h"
#include <iostream>
using namespace std;
namespace HiveSpace
{
//Provide a constructor which also invokes the base class constructor
Drone::Drone(int lifespan, char fertile) : Bee(lifespan)
{
// this->fertile = fertile ;
}
void Drone::work()
{
cout << "Drone derived class working " << endl;
}
}
#ifndef QUEEN_H
#define QUEEN_H
#include "Bee.h"
namespace HiveSpace
{
class Queen : Bee /*indicate that a Queen IS A Bee*/
{
private:
int numBabies;
public:
Queen(int lifespan, int numBabies);
virtual void work();
};
}
#endif
///
#include "Queen.h"
#include <iostream>
using namespace std;
namespace HiveSpace
{
//Provide a constructor which also invokes the base class constructor
Queen::Queen(int lifespan, int numBabies) : Bee(lifespan)
{
this->numBabies = numBabies ;
}
void Queen::work()
{
cout << "Queen derived class working"<< endl;
numBabies++;
}
}
////
#ifndef WORKER_H
#define WORKER_H
#include "Bee.h"
namespace HiveSpace
{
class Worker : Bee /*Indicate that a Worker IS A Bee*/
{
private:
int honeyMade;
public:
Worker(int lifespan, int honeyMade);
virtual void work();
};
}
#endif
///
#include "Worker.h"
#include <iostream>
using namespace std;
namespace HiveSpace
{
//Provide a constructor which also invokes the base class constructor
Worker::Worker(int lifespan, int honeyMade) : Bee(lifespan)
{
this->honeyMade = honeyMade ;
}
void Worker::work()
{
cout << "Worker derived class working" << endl;
honeyMade++;
}
}
Related
For some fun purposes, I'm writing a Tetris game. I created two classes: "GameBackground" and "Tetromino". Since the "Tetromino" class has a dependency on the "GameBackground" class, I injected this dependency in the constructor using an interface such that I can test the "Tetromino" class independent of the GameBackground class by mocking it. When I use gmock to create the "GameBackgroundMock", the test fails. When I use my own mock like
class MyOwnMock : public IGameBackground {
public:
MyOwnMock() : IGameBackground() {
};
bool RequestSpaceOnGrid(TetrominoPositionType requested_coordinates) override{
return true;
}
};
then the test passes. Apparently, I don't use the gmock in the right way. I would appreciate any suggestion leading to a green test by using gmock.
For implementation details see the following code basis.
My initial folder structure looks as follows:
[Project structure][1]
[1]: https://i.stack.imgur.com/7h8zT.png
The corresponding files at the project's top-level:
CMakeLists.txt.in:
# see https://github.com/google/googletest/blob/master/googletest/README.md#incorporating-into-an-existing-cmake-project
cmake_minimum_required(VERSION 2.8.2)
project(googletest-download NONE)
include(ExternalProject)
ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG master
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
CMakeLists.txt:
cmake_minimum_required(VERSION 3.11.3)
project(Test)
set(CMAKE_CXX_STANDARD 17)
# Download and unpack googletest at configure time
# (see https://github.com/google/googletest/blob/master/googletest/README.md#incorporating-into-an-existing-cmake-project)
configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
if(result)
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
if(result)
message(FATAL_ERROR "Build step for googletest failed: ${result}")
endif()
# Add googletest directly to our build. This defines the gtest and gtest_main targets.
add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src
${CMAKE_CURRENT_BINARY_DIR}/googletest-build
EXCLUDE_FROM_ALL)
add_subdirectory(src)
add_subdirectory(test)
The content of the src folder:
CMakeLists.txt:
cmake_minimum_required(VERSION 3.11.3)
add_library(GameBackground_Lib STATIC GameBackground.cpp)
add_library(Tetromino_Lib STATIC Tetromino.cpp)
IGameBackground.h
#ifndef TEST_IGAMEBACKGROUND_H
#define TEST_IGAMEBACKGROUND_H
#include <utility>
#include <vector>
#include <iostream>
using TetrominoPositionType = std::vector<std::pair<int, int>>;
class IGameBackground {
public:
virtual ~IGameBackground() = default;
virtual bool RequestSpaceOnGrid(TetrominoPositionType) = 0;
};
#endif //TEST_IGAMEBACKGROUND_H
GameBackground.h
#ifndef TEST_GAMEBACKGROUND_H
#define TEST_GAMEBACKGROUND_H
#include "IGameBackground.h"
#include <tuple>
#include <utility>
#include <vector>
class GameBackground : public IGameBackground {
public:
GameBackground(int, int);
bool RequestSpaceOnGrid(TetrominoPositionType) override;
private:
int m_horizontal_grid_size;
int m_vertical_grid_size;
int m_nr_buttomlines_filled{};
std::vector<std::vector<bool>> m_occupancy_grid{};
};
#endif //TEST_GAMEBACKGROUND_H
GameBackground.cpp
#include "GameBackground.h"
GameBackground::GameBackground(int vertical_grid_size, int horizontal_grid_size)
: m_horizontal_grid_size{horizontal_grid_size},
m_vertical_grid_size{vertical_grid_size} {
m_occupancy_grid.resize(vertical_grid_size);
for (auto &row : m_occupancy_grid) {
row.resize(horizontal_grid_size);
}
}
bool GameBackground::RequestSpaceOnGrid(
TetrominoPositionType requested_coordinates) {
bool is_every_coordinate_within_bounds{true};
for (const auto &position : requested_coordinates) {
int pos_x{position.first}, pos_y{position.second};
if (pos_x < 0 || pos_x >= m_vertical_grid_size || pos_y < 0 ||
pos_y >= m_horizontal_grid_size) {
is_every_coordinate_within_bounds = false;
break;
}
}
bool is_request_successfull{false};
if (is_every_coordinate_within_bounds) {
try {
bool is_occupied{false};
for (const auto &position : requested_coordinates) {
int row{position.first}, column{position.second};
is_occupied |= m_occupancy_grid.at(row).at(column);
}
if (!is_occupied) {
for (const auto &position : requested_coordinates) {
int row{position.first}, column{position.second};
m_occupancy_grid.at(row).at(column) = true;
}
is_request_successfull = true;
}
} catch (std::out_of_range const &e) {
std::cerr << e.what() << '\n';
}
}
return is_request_successfull;
}
Tetromino.h
#ifndef TEST_TETROMINO_H
#define TEST_TETROMINO_H
#include <memory>
#include <utility>
#include <vector>
#include "IGameBackground.h"
enum class Direction { left, right, down };
using TetrominoPositionType = std::vector<std::pair<int, int>>;
class Tetromino {
public:
Tetromino(IGameBackground&, TetrominoPositionType);
TetrominoPositionType getPosition();
void setPosition(TetrominoPositionType);
void moveOneStep(Direction);
private:
TetrominoPositionType m_position;
IGameBackground& m_game_background;
};
#endif //TEST_TETROMINO_H
Tetromino.cpp
#include "Tetromino.h"
#include <utility>
Tetromino::Tetromino(IGameBackground &game_background,
TetrominoPositionType init_position)
: m_game_background{game_background},
m_position{std::move(init_position)} {};
TetrominoPositionType Tetromino::getPosition() { return m_position; }
void Tetromino::setPosition(TetrominoPositionType position) {
m_position = std::move(position);
}
void Tetromino::moveOneStep(Direction direction) {
TetrominoPositionType position = getPosition();
switch (direction) {
case Direction::down:
for (auto &pos : position) {
++pos.first;
}
if (m_game_background.RequestSpaceOnGrid(position)) {
setPosition(position);
}
break;
case Direction::left:
for (auto &pos : position) {
--pos.second;
}
if (m_game_background.RequestSpaceOnGrid(position)) {
setPosition(position);
}
break;
case Direction::right:
for (auto &pos : position) {
++pos.second;
}
if (m_game_background.RequestSpaceOnGrid(position)) {
setPosition(position);
}
break;
}
}
The content of the test folder
CMakeLists.txt
cmake_minimum_required(VERSION 3.11.3)
add_executable(TetrominoTest TetrominoTest.cpp)
target_link_libraries(TetrominoTest gmock_main gtest_main Tetromino_Lib)
TetrominoTest.cpp
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "../src/IGameBackground.h"
#include "../src/Tetromino.h"
//class MyOwnMock : public IGameBackground {
//public:
// MyOwnMock() : IGameBackground() {
// };
// bool RequestSpaceOnGrid(TetrominoPositionType requested_coordinates) override{
// return true;
// }
//};
class GameBackgroundMock : public IGameBackground {
public:
GameBackgroundMock() : IGameBackground() {
};
MOCK_METHOD(bool, RequestSpaceOnGrid,
(TetrominoPositionType requested_coordinates), (override));
};
class MoveTetromino : public ::testing::Test {
protected:
MoveTetromino() : unit_under_test(a_mock, init_position) {};
TetrominoPositionType init_position{{0, 0},
{0, 1},
{0, 2},
{0, 3}};
Tetromino unit_under_test;
GameBackgroundMock a_mock;
//MyOwnMock a_mock;
};
TEST_F(MoveTetromino, move_right) {
TetrominoPositionType current_position{init_position};
TetrominoPositionType expected_position{init_position};
for (auto &elem : expected_position) {
elem.second++;
}
ON_CALL(a_mock, RequestSpaceOnGrid(current_position)).WillByDefault(::testing::Return(true));
unit_under_test.moveOneStep(Direction::right);
TetrominoPositionType actual_position = unit_under_test.getPosition();
EXPECT_EQ(expected_position, actual_position);
}
You're using ON_CALL which sets a default value to be returned when a mocked method is being called. This is useful if you don't care how many times given method will be called in your tests and you just set a default value to be returned any number of times (however, expect calls are being matched first, it's a longer story).
It's better to use EXPECT_CALL in your case to explicitly state what actions you anticipate and validate them:
EXPECT_CALL(a_mock, RequestSpaceOnGrid(current_position)).WillOnce(::testing::Return(true));
If you will use this, gmock will let you know what's wrong with the test: the RequestSpaceOnGrid was called, however not with current_position but with expected_position. Not sure if this is expected, but this is what happens in the test.
The test passes by calling either
ON_CALL(a_mock, RequestSpaceOnGrid(expected_position)).WillByDefault(::testing::Return(true));
or as Quarra suggested
EXPECT_CALL(a_mock, RequestSpaceOnGrid(expected_position)).WillOnce(::testing::Return(true));
The crucial point was to give expected_position instead of current_position to the mocked RequestSpaceOnGrid method.
Another possibility would be to get the test green to call the mocked method with ::testing::_
ON_CALL(a_mock, RequestSpaceOnGrid(::testing::_)).WillByDefault(::testing::Return(true));
In this case, the mocked method would always return true independent of the given argument.
I would like to modify the clang AST using a plugin.
I have following the suggestions of using Clang Rewriter object.
I use compiler.createDefaultOutputFile() to obtain the output stream to write the changed file into it.
the compilation works fine but the generated object file is broken.
I get the following linker error: "File format not recognized".
Build command line:
clang++-8 -Xclang -load -Xclang libcashpp.so -Xclang -add-plugin -Xclang cash-pp test.cpp
Build Output:
/tmp/test-eb7d3d.o: file not recognized: File format not recognized
Question:
Is it actually possible to update the AST using a clang plugin?
Can someone point me to an example program that does that?
Source Code:
#include <clang/Frontend/FrontendPluginRegistry.h>
#include <clang/AST/AST.h>
#include <clang/AST/ASTConsumer.h>
#include <clang/AST/RecursiveASTVisitor.h>
#include "clang/Rewrite/Core/Rewriter.h"
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Sema/Sema.h>
#include <llvm/Support/raw_ostream.h>
#include <string>
#include <sstream>
namespace {
class VarDeclVisitor : public clang::RecursiveASTVisitor<VarDeclVisitor> {
public:
VarDeclVisitor(clang::Rewriter& rewriter)
: rewriter_(rewriter)
{}
bool VisitCallExpr(clang::CallExpr *ce) {
auto q = ce->getType();
auto t = q.getTypePtrOrNull();
if (t != NULL) {
auto callee = ce->getDirectCallee();
auto funcName = callee->getNameInfo().getAsString();
if (funcName == "getInstanceName") {
rewriter_.ReplaceText(ce->getBeginLoc(), callee->getIdentifier()->getName().size(), "getInstanceName2");
}
}
return true;
}
private:
clang::Rewriter& rewriter_;
};
class MyASTConsumer : public clang::ASTConsumer {
using Base = clang::ASTConsumer;
public:
MyASTConsumer(std::unique_ptr<llvm::raw_pwrite_stream>&& os)
: os_(std::move(os))
{}
void HandleTranslationUnit(clang::ASTContext &context) override {
clang::Rewriter rewriter(context.getSourceManager(), context.getLangOpts());
VarDeclVisitor visitor(rewriter);
auto &source_manager = context.getSourceManager();
const auto &mainFileID = source_manager.getMainFileID();
const auto &decls = context.getTranslationUnitDecl()->decls();
for (auto &decl : decls) {
const auto &fileID = source_manager.getFileID(decl->getLocation());
if (fileID != mainFileID)
continue;
visitor.TraverseDecl(decl);
}
auto rwbuf = rewriter.getRewriteBufferFor(mainFileID);
if (rwbuf) {
*os_ << std::string(rwbuf->begin(), rwbuf->end());
} else {
*os_ << source_manager.getBufferData(mainFileID);
}
}
private:
std::unique_ptr<llvm::raw_pwrite_stream> os_;
};
class MyPlugin : public clang::PluginASTAction {
public:
std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance &compiler,
llvm::StringRef inFile) override {
auto os = compiler.createDefaultOutputFile(false, inFile, "cpp");
if (!os)
return nullptr;
return std::make_unique<MyASTConsumer>(std::move(os));
}
bool ParseArgs(const clang::CompilerInstance &compiler,
const std::vector<std::string> &args) override {
return true;
}
void PrintHelp(llvm::raw_ostream &ros) {}
};
}
static clang::FrontendPluginRegistry::Add<MyPlugin>
X("cash-pp", "My plugin");
I want to use Qtimer to pause executing of given block of codes, while in another thread it does something else. I connected the timeout of the thread with qeventloop quit, but the problem is, that the timeout is not called. When another emit occures, the timeout is magically triggered or if I add another connect the time out is triggered too. I think I miss something about the use of qtimer, qeventloop and qthread. Can anyone help? I extracted the basic code for testing and put it here:
main.cpp
#include "widget.h"
#include <QApplication>
#include "tim.h"
#include <QThread>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget *w=new Widget();
tim *t=new tim();
QThread *thread=new QThread();
t->moveToThread(thread);
thread->start();
QThread::connect(w,SIGNAL(signalDoIt()),t,SLOT(slotDoIt()),Qt::QueuedConnection);
QThread::connect(w,SIGNAL(signalQuitTimer()),t,SLOT(slotQuitTimer()),Qt::QueuedConnection);
QThread::connect(t,SIGNAL(signalSetText(QString)),w,SLOT(slotSetText(QString)),Qt::QueuedConnection);
w->show();
return a.exec();
}
tim.h
#ifndef TIM_H
#define TIM_H
#include <QObject>
#include<QTimer>
#include<QTime>
#include<QEventLoop>
#include<QThread>
#include<QDebug>
class tim : public QObject
{
Q_OBJECT
public:
tim();
~tim();
signals:
void signalSetText(QString);
public slots:
void slotDoIt();
void slotQuitTimer();
void slotShowTime();
private:
QTimer *trainingTimer;
QEventLoop loopTrainingWait;
QTime time;
};
#endif // TIM_H
tim.cpp
#include "tim.h"
tim::tim()
{
qDebug()<<"constructor";
trainingTimer=new QTimer(this);
trainingTimer->setTimerType(Qt::PreciseTimer);
trainingTimer->setSingleShot(true);
QThread::connect(trainingTimer,SIGNAL(timeout()),&loopTrainingWait,SLOT(quit()));
// QThread::connect(trainingTimer,SIGNAL(timeout()),this,SLOT(slotShowTime())); //to uncomment all works, but withou this, it does not
}
void tim::slotDoIt()
{
trainingTimer->start(5000);
time.start();
loopTrainingWait.exec();
QString text(QString::number(loopTrainingWait.isRunning())+" "+ QString::number(time.elapsed()));
qDebug()<<text;
emit signalSetText(text);
}
void tim::slotShowTime()
{
QString text(QString::number(loopTrainingWait.isRunning())+" slot "+ QString::number(time.elapsed()));
qDebug()<<text;
emit signalSetText(text);
}
void tim::slotQuitTimer()
{
if(loopTrainingWait.isRunning())
loopTrainingWait.quit();
if(trainingTimer->isActive())
trainingTimer->stop();
}
tim::~tim()
{
}
//gui for testing
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
public slots:
void slotSetText(QString text);
signals:
void signalDoIt();
void signalQuitTimer();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
void Widget::slotSetText(QString text)
{
ui->label->setText(text);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
this->close();
}
void Widget::on_pushButton_2_clicked()
{
emit signalDoIt();
}
void Widget::on_pushButton_3_clicked()
{
emit signalQuitTimer();
}
I met the same issue,and eventually I wrote SLOT between public and :,then it works
the problem was in static qeventloop, making this dynamic
loopTrainingWait=new QEventLoop(this);
with parent this, resolved the issue
I am using Qt 5.3 and trying to develop application for IOS.
Problem is, QWidget application in a iPhone Retina simulator:
QMessage becomes full-screen.
In Application output panel I see: This plugin does not support
propagateSizeHints().
So looking for alternative solution for QMessageBox. I don't want to learn QML yet.
If you do an overlay on top of your widget you can make something similar to the iOS popups.
Basically you create another widget, and you parent it to the widget you want it to be drawn on top of.
Here are some helpful flags and lines of code to put in your overlay constructor:
setPalette(Qt::transparent);
// if you have buttons on this overlay you probably don't want this one
setAttribute(Qt::WA_TransparentForMouseEvents);
QGraphicsDropShadowEffect * dse = new QGraphicsDropShadowEffect();
dse->setBlurRadius(20);
this->setGraphicsEffect(dse);
Then be sure to command a resize of your overlay when the parent widget resizes:
void ParentWidget::resizeEvent(QResizeEvent *event)
{
overlay->resize(event->size());
event->accept();
}
http://www.qtcentre.org/wiki/index.php?title=Widget_Overlay
UPDATE: Awesome example
main.cpp
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
w.resize(300,600);
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "overlaydialogbox.h"
#include <QResizeEvent>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void resizeEvent(QResizeEvent *event);
private:
OverlayDialogBox * m_overlay;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
m_overlay = new OverlayDialogBox(this);
}
MainWindow::~MainWindow() { }
void MainWindow::resizeEvent(QResizeEvent *event)
{
m_overlay->resize(event->size());
event->accept();
}
overlaydialogbox.h
#ifndef OVERLAYDIALOGBOX_H
#define OVERLAYDIALOGBOX_H
#include <QWidget>
class OverlayDialogBox : public QWidget
{
Q_OBJECT
public:
explicit OverlayDialogBox(QWidget *parent = 0);
signals:
void accepted();
void rejected();
void finished(int);
public slots:
};
#endif // OVERLAYDIALOGBOX_H
overlaydialogbox.cpp
#include "overlaydialogbox.h"
#include <QGridLayout>
#include <QGraphicsEffect>
#include <QLabel>
#include <QDialogButtonBox>
#include <QMessageBox>
#include <QIcon>
OverlayDialogBox::OverlayDialogBox(QWidget *parent) :
QWidget(parent)
{
setPalette(Qt::transparent);
// if you have buttons on this overlay you probably don't want this one
// setAttribute(Qt::WA_TransparentForMouseEvents);
QGraphicsDropShadowEffect * dse = new QGraphicsDropShadowEffect();
dse->setBlurRadius(20);
this->setGraphicsEffect(dse);
QGridLayout * grid = new QGridLayout();
this->setLayout(grid);
QMessageBox * msg = new QMessageBox(QMessageBox::Warning,"Testing","This is a test QMessageBox.");
QObject::connect(msg, SIGNAL(accepted()), this, SIGNAL(accepted()));
QObject::connect(msg, SIGNAL(finished(int)), this, SIGNAL(finished(int)));
QObject::connect(msg, SIGNAL(rejected()), this, SIGNAL(rejected()));
QObject::connect(msg, SIGNAL(finished(int)), this, SLOT(close()));
msg->setPalette(Qt::white);
grid->addWidget(msg);
}
Hope that helps.
This questions is a bit annoying, I can't get the following code to compile. You will have to compile the code below.
I am having some trouble with boost asio, I am trying to abstract the logic of accepting connections into a uniform abstraction so that I can initiate connection for windows named-pipes and Unix domain sockets uniformly with regular TCP/IP.
There are 3 classes shown in the code below, the first 2 are the implementations of acceping TCP connections, and the third class below is a generic class that is implemented in terms of the first 2. I am having troubles with boost::bind calls. The trouble probably lies with my understanding of the semantics.
If I make TcpDestinationAcceptor::handle_accept a regular member function (--i.e., not a template member function) which results in me not passing the AcceptHandler parameter. The code compiles fine. Note: I do not remove the template function status from TcpDestinationAcceptor::StartAccepting.
Note: I have already started on a different design, still I would like to pursue this design if possible.
Self contained code:
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/asio/placeholders.hpp>
class TcpDestinationConnection
{
public:
typedef boost::asio::ip::tcp::socket t_io_object;
TcpDestinationConnection(boost::asio::io_service & io_s)
: m_io_object(io_s) {} ;
t_io_object & io_object() { return m_io_object; }
private:
t_io_object m_io_object;
};
class TcpDestinationAcceptor
{
public:
typedef boost::asio::ip::tcp::acceptor t_acceptor;
typedef boost::shared_ptr<TcpDestinationConnection> t_connection_ptr;
TcpDestinationAcceptor( boost::asio::io_service & io_s)
: m_io_service(io_s),
m_acceptor(io_s)
{
m_acceptor.open(boost::asio::ip::tcp::v4());
}
TcpDestinationAcceptor( boost::asio::io_service & io_s ,
const boost::asio::ip::tcp::endpoint & endpoint)
: m_io_service(io_s),
m_acceptor(io_s, endpoint)
{
m_acceptor.open(boost::asio::ip::tcp::v4());
}
t_acceptor & acceptor() { return m_acceptor; }
template<typename AcceptHandler>
void StartAccepting(AcceptHandler h)
{
t_connection_ptr new_session(new TcpDestinationConnection(m_io_service));
m_acceptor.async_accept( new_session->io_object(),
boost::bind( &TcpDestinationAcceptor::handle_accept<AcceptHandler>, this,
boost::asio::placeholders::error, new_session, h));
}
template<typename AcceptHandler>
void handle_accept(const boost::system::error_code & err, t_connection_ptr cur, AcceptHandler h) {
}
private:
boost::asio::io_service & m_io_service;
boost::asio::ip::tcp::acceptor m_acceptor;
};
template<typename t_acceptor>
class ConnectionOracle
{
public:
ConnectionOracle()
: m_io_service(),
m_acceptor(m_io_service) {}
typename t_acceptor::t_acceptor & native_acceptor() { return m_acceptor.acceptor(); }
boost::asio::io_service & io_service() { return m_io_service; }
void StartConnection( typename t_acceptor::t_connection_ptr connection,
boost::system::error_code & error)
{
}
void Begin()
{
m_acceptor.StartAccepting( boost::bind( &ConnectionOracle::StartConnection,this,
_1,
boost::asio::placeholders::error));
m_io_service.run();
}
private:
boost::asio::io_service m_io_service;
t_acceptor m_acceptor;
};
int main()
{
ConnectionOracle<TcpDestinationAcceptor> ConOracle;
ConOracle.native_acceptor().
bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(),50000));
ConOracle.Begin();
return 0;
}